Package: libzenohc-dev Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 129 Depends: libzenohc (=0.10.0~rc) Filename: ./0.10.0-rc/libzenohc-dev_0.10.0-rc_amd64.deb Size: 26680 MD5sum: 665a5e72e8444c7db14311b326ba2715 SHA1: dc82f1533ed7d66dfd00e3f45f040751de772914 SHA256: 589b1cfb25df0a469af11e130257c82221e13c936fa9c1c21f8588a95cb2101d SHA512: 737ce65fa1902d0ee1d6d9fd59ddd55626da346c50e7a600f7bece9a129298736a1ab9777d902951ac562423148277adfa06d5d470340be6a81c0dbf6bc5336b Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script sligthly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documenation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Link to targets `zenohc::lib` for dynamic library and `zenohc::static` for static one in your CMakeLists.txt configuration file. . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behaviour can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps aditional efforts are neccesary, that will depend of your enviroment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionaly you can use `RUSTFLAGS` enviroment variable for lead the compilation. . - . . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 129 Depends: libzenohc (=0.10.0~rc) Filename: ./0.10.0-rc/libzenohc-dev_0.10.0-rc_arm64.deb Size: 26700 MD5sum: bc50084b16feb7eca36ab138408406d2 SHA1: 5e350e1cb84e86eae8aadb70d23cd5abe8e0d3cf SHA256: 6a8272d4b28ea7fe395d0919720fc76f7c4d066e539053afa91bdd5de137046e SHA512: fc2b97472dd0bb7319a00a44a4a1eb181e3ec053cc5888934ab65b70830deb790d204607a58c98b3497d0d0348824f775e80be0388e11d072630cdebc979a437 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script sligthly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documenation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Link to targets `zenohc::lib` for dynamic library and `zenohc::static` for static one in your CMakeLists.txt configuration file. . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behaviour can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps aditional efforts are neccesary, that will depend of your enviroment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionaly you can use `RUSTFLAGS` enviroment variable for lead the compilation. . - . . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 129 Depends: libzenohc (=0.10.0~rc) Filename: ./0.10.0-rc/libzenohc-dev_0.10.0-rc_armel.deb Size: 26700 MD5sum: 618b8598a122025c38dfbf549f180ebe SHA1: 1bda8f85f5dfddaea20b79a4cab78962485ddcd1 SHA256: 9529324e001dca0659a5f901dddd6e683aa616c7af8615f873e5f67397e44ac2 SHA512: 4df19fef43844597c2cee7599c4fbed93490fd7d1f8dd329b7845774bb513ad25e3371513addb902d66c85424b259f20c5cf56eb596d352ac2e1cdcbe7e5abed Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script sligthly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documenation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Link to targets `zenohc::lib` for dynamic library and `zenohc::static` for static one in your CMakeLists.txt configuration file. . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behaviour can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps aditional efforts are neccesary, that will depend of your enviroment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionaly you can use `RUSTFLAGS` enviroment variable for lead the compilation. . - . . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 129 Depends: libzenohc (=0.10.0~rc) Filename: ./0.10.0-rc/libzenohc-dev_0.10.0-rc_armhf.deb Size: 26684 MD5sum: 74e04a773afa8583205cffcc0091b54a SHA1: e5a6622192cbfcbcfe1edfac2a2a6fedd9781ba3 SHA256: 478db109adb57800e3ba4f1db42bcf2e99093e7ac55a767e1bc9ab61b26310e5 SHA512: 4f3fbb232738edbac46e2df920816a0cb6ca02a7bcae095c77470e313c306a0a4e3df523090f875578c9bec980fbd709fee370efaba4ea00ea4f347305412fc8 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script sligthly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documenation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Link to targets `zenohc::lib` for dynamic library and `zenohc::static` for static one in your CMakeLists.txt configuration file. . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behaviour can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps aditional efforts are neccesary, that will depend of your enviroment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionaly you can use `RUSTFLAGS` enviroment variable for lead the compilation. . - . . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13184 Depends: libc6 (>= 2.29) Filename: ./0.10.0-rc/libzenohc_0.10.0-rc_amd64.deb Size: 3538660 MD5sum: 6054cc8ff1f4909bc173d9dc1ffc0659 SHA1: 49f12215775be41f7d36189c727f16f8dbadaff0 SHA256: d76a681535fd4fd92090967d68f0115a04e25a3cc4e519a9552c658f74dd944a SHA512: 1cbd71cdec69f8dcca46d8c83cd50f5403552550133ba217b70058d0391ce9e1f5fbcc9c2ea9cd800072a19253f2c3411cdb1190cc34ed9a8611607085daf717 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script sligthly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documenation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Link to targets `zenohc::lib` for dynamic library and `zenohc::static` for static one in your CMakeLists.txt configuration file. . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behaviour can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps aditional efforts are neccesary, that will depend of your enviroment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionaly you can use `RUSTFLAGS` enviroment variable for lead the compilation. . - . . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11871 Depends: libc6:arm64 (>= 2.31) Filename: ./0.10.0-rc/libzenohc_0.10.0-rc_arm64.deb Size: 3176184 MD5sum: 80f200eadf14e184ec53c9ba66c97dae SHA1: 7b9ca457a9ae4db095bcbff6af55f4e529291449 SHA256: 134d91c6280e0ee5262bc478a56d342c7780f33c60e3504d2745c87a0485c607 SHA512: 439feca1975f1c97cee302b0142c5f9411f53f9cf0fd24bd8781532f9bfbfa19d77fb607bce84fb7af6e7d5f43016b8d229673db736455a0e8b2d298c0800b21 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script sligthly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documenation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Link to targets `zenohc::lib` for dynamic library and `zenohc::static` for static one in your CMakeLists.txt configuration file. . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behaviour can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps aditional efforts are neccesary, that will depend of your enviroment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionaly you can use `RUSTFLAGS` enviroment variable for lead the compilation. . - . . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12274 Depends: libc6:armel (>= 2.31) Filename: ./0.10.0-rc/libzenohc_0.10.0-rc_armel.deb Size: 3309652 MD5sum: 124ad9458c2cc0fe0a082c1cffc11c89 SHA1: 711bdbd4e53c2df650017d15115c759844767ec5 SHA256: ba4d320ac08c84ed3f5a50506f4830a4d3412ab14dd32e5abcc82f0b744e1e00 SHA512: 651f46ccf51319a314d2f95e973619b5c8112d99c9465c7e9e1399d2121887a73b036bc018ba8028d5d722eab91245e2e6fad441abd46fd5285f249a9bded0fb Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script sligthly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documenation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Link to targets `zenohc::lib` for dynamic library and `zenohc::static` for static one in your CMakeLists.txt configuration file. . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behaviour can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps aditional efforts are neccesary, that will depend of your enviroment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionaly you can use `RUSTFLAGS` enviroment variable for lead the compilation. . - . . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12070 Depends: libc6:armhf (>= 2.31) Filename: ./0.10.0-rc/libzenohc_0.10.0-rc_armhf.deb Size: 3299692 MD5sum: 29c51fdea9832724080e66bf50221735 SHA1: 06bc84766277bcc3529fc62e91609c7c6588dc11 SHA256: 4fb714866d33403cc001fa2e4120ed3fbbbe0d0b6f0a71dea8526b01387ccb56 SHA512: 5fc4a5644c9da482da573225dedc6713bb7c32927a35da96f26f72e1fc250331244d90aa8d163312997b7fd80ac7990b02aa0e2e3e2dcda36a06a8adbcb18d77 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script sligthly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documenation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Link to targets `zenohc::lib` for dynamic library and `zenohc::static` for static one in your CMakeLists.txt configuration file. . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behaviour can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps aditional efforts are neccesary, that will depend of your enviroment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionaly you can use `RUSTFLAGS` enviroment variable for lead the compilation. . - . . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: zenoh-backend-filesystem Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9943 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-filesystem_0.10.0-rc_amd64.deb Size: 3051712 MD5sum: b9ea79c095b8b1f6a52e7624e52e9ed3 SHA1: 60addf4463b874b95d65b0d921e1b1ee7b827ff0 SHA256: 4c719db5039fa8dff75c8bc1424ad6f82a06d608b895aeefed61382244d6d5fb SHA512: 9441d8f4baf508ab2eb44f6ffefb687052015436062661ff76996e3069d819e8f3456bfdb506d97083ac2b45db2daf7fc1a5c5d7afbd5d9c059b6b24ca2d31a8 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8743 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-filesystem_0.10.0-rc_arm64.deb Size: 2651852 MD5sum: 03bb502ea7ffebeb6adcd801a1cc08a8 SHA1: ccb7b9fcf8aeddd0df3be1dbc9d97764513d5666 SHA256: 43a30258e92e51631c278c9cfbdd5e6b5d50f8a9858084ad7e44eccf382af8ae SHA512: de2eaaec5649b7fee05e1475694d0a728918c31325d4a6a559d4e05450793a19c70e11a80074c6b89f6d87a061387665e7792af23f215fff162b5d2b5116cc4d Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8326 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-filesystem_0.10.0-rc_armel.deb Size: 2594748 MD5sum: 84648e53008ee43dd4d287248cc673b6 SHA1: d01212b13363582181417eb96083e8bd1dc2250b SHA256: e8b8a5cd00b9055cba85ed3f54729e4ac07ce46ec8870d60f2a84d32c055f031 SHA512: a790330c8ee5ca4c0fa45249661f4de2a4bbccfb1e80b5a30d98f81a9eed1adae0b6c72f726e9fce398f92fae68d532d0954c3b697a802229b54815b274d7267 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6554 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-filesystem_0.10.0-rc_armhf.deb Size: 2695500 MD5sum: 6ab639279a0396cf487f92b5e1d5da5f SHA1: e896c7824fd13811e1ab91677ce31535544ab76f SHA256: 3e34f4674f1474f5b130eed939cd8266f066857eeb0419e8e4c5a7a65d057b7b SHA512: af16a35c379fd0aa14780a046aff74851b0875e8bd7f3a97ca175aafa91cc77d9ec29144e896076eac8b7600eaf375b21edc1dc296d289775b1b13fb87fa6b2c Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-influxdb Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5337 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-influxdb_0.10.0-rc_amd64.deb Size: 1671028 MD5sum: 71259d952276fb71ebc92186fa2c7eec SHA1: 2991431a9e96b5195e6f76cb446c4f05708e3f81 SHA256: 6433ba00de5315635b29d68634e3fc08e807dc25a65e4c8f8eaaade326e0c35a SHA512: 902c9bfb9fe4e4771b77191f9af80422a628b52f5513953956290c55ad811fb88f503db7fc19d79bb46038fdb7547e4c57bbba2e176605debf1ff07895dbb17d Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . :warning: InfluxDB 2.x is not yet supported. InfluxDB 1.8 minimum is required. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { id: "influxdb", // the database name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { // If needed: InfluxDB credentials, with read/write privileges for the database //username: "user", //password: "password" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` gate, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` gate. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"username"`** (optional, string) : an InfluxDB user name (usually [non-admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#non-admin-users)). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . - **`"password"`** (optional, string) : the user's password. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). After a delay (5 seconds), the measurement corresponding to the deleted key is dropped if it still contains no points. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4801 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-influxdb_0.10.0-rc_arm64.deb Size: 1489788 MD5sum: 402cfbb5a497ed25e684f915a6daf4e9 SHA1: 56689b08d0707168779d44f41148bd3c94749105 SHA256: 3b520c402ed04e4a526ea1c4760a88d1583202a0f83f5303880a19d0b2c2a13b SHA512: b923406e4049c3251fcb197eb9ce2ff1b70b43d428d7549756d459cd01fcb34cb2026be9ab1ed3ec44e52a61eca4fd3b60fcd80568f6d5b6714dd60f26ebfffd Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . :warning: InfluxDB 2.x is not yet supported. InfluxDB 1.8 minimum is required. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { id: "influxdb", // the database name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { // If needed: InfluxDB credentials, with read/write privileges for the database //username: "user", //password: "password" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` gate, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` gate. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"username"`** (optional, string) : an InfluxDB user name (usually [non-admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#non-admin-users)). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . - **`"password"`** (optional, string) : the user's password. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). After a delay (5 seconds), the measurement corresponding to the deleted key is dropped if it still contains no points. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4260 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-influxdb_0.10.0-rc_armel.deb Size: 1288424 MD5sum: 300c94481d63e1951813183f03aaa841 SHA1: 7781bc36b66c6be1a61493f141e4636339d15163 SHA256: b7de9536083ee1ab4c898c304a5069ebfb6d8305cb308ecb4c4b3d215cdc7bd8 SHA512: d7108c5c9589d971b4d2b83390977e94b2a2d6be03a6a3df02703ce0d3fc8fd148dafa924c59e41a704157e9948049c6194fb86ebc903511aa46dacbc542dd78 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . :warning: InfluxDB 2.x is not yet supported. InfluxDB 1.8 minimum is required. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { id: "influxdb", // the database name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { // If needed: InfluxDB credentials, with read/write privileges for the database //username: "user", //password: "password" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` gate, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` gate. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"username"`** (optional, string) : an InfluxDB user name (usually [non-admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#non-admin-users)). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . - **`"password"`** (optional, string) : the user's password. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). After a delay (5 seconds), the measurement corresponding to the deleted key is dropped if it still contains no points. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4156 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-influxdb_0.10.0-rc_armhf.deb Size: 1280768 MD5sum: 76dd25575a3151221b6edf18663f23a9 SHA1: 8eb85bafe8705b718487d44680fdef38c8a03515 SHA256: f2a89e4918e3bebf07f9d13e1e6100437d8e6b717a33a577d349c658129c7ce1 SHA512: 4d8fe614ef4a7fee26b4ff860a348098b9186bf33b47ecedf2956640b570acb9cb00250b22d3b009771d43b9104515b55dd7155b6711da8147fcb428787463ac Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . :warning: InfluxDB 2.x is not yet supported. InfluxDB 1.8 minimum is required. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { id: "influxdb", // the database name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { // If needed: InfluxDB credentials, with read/write privileges for the database //username: "user", //password: "password" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` gate, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` gate. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"username"`** (optional, string) : an InfluxDB user name (usually [non-admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#non-admin-users)). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . - **`"password"`** (optional, string) : the user's password. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). After a delay (5 seconds), the measurement corresponding to the deleted key is dropped if it still contains no points. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-rocksdb Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9845 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-rocksdb_0.10.0-rc_amd64.deb Size: 3034288 MD5sum: dadc9b33141790f3f340a95eed1717af SHA1: 65ce7d028b7f14e1282284d42ca3824bd8bb7565 SHA256: 8e27971932bbd8237655bef4a054669eff0547e9737ce12cd7f0ffc889ca77a1 SHA512: cb8e7b370b388c6dc88f2affd805e08779ad086c1bbf9b114802e814de810380d20e8ec9b9021a589ead74a8f43458cccc79a779d35c0be6c74ba872442ea97b Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8633 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-rocksdb_0.10.0-rc_arm64.deb Size: 2628352 MD5sum: 7cb2aeffb7a6a2bd623d153275223910 SHA1: 37bd7a955b51aa87922457e96bbc8970e270af72 SHA256: fbd3460fa9bf3faf696eafef97abfee996cced9ac8b1890ea36751fb1e4d5c8e SHA512: 84d409c323ed7390e5973410bdb6ca38a6e296c75817310ccfae1c9f41fd1dffd56b2cac5ba026b7ecf6dcd16f67d2568ebc4fa1f7efb0cd62433148e577a339 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8288 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-rocksdb_0.10.0-rc_armel.deb Size: 2579416 MD5sum: 41f1351fac1e4dc51eadf726f21868f7 SHA1: e71954b538cd3e719b8b70d4f2d6d69c4201e41d SHA256: 2b7abefc530621d6944f4b7277e69ab70f8b4998569e6fc620fdd82c4f26b87e SHA512: 0470373b0d4346cf6bc2e9e263683f0885049bf2fdf716a47f6a89428462f2345e1697231f77ea3fb8ca4609d171f47b2ea8ccbebcaab814cfe7712a6547cf9a Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6472 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-rocksdb_0.10.0-rc_armhf.deb Size: 2682244 MD5sum: 6467ff17ed6c7bbccfb96a8d5110f029 SHA1: de7c7f014934fb777104aef1e844d0e7db7db05c SHA256: 1e0eb67ec9340216ced90de0336c9b4817a3c9a366124d82db2550d7c25c1c92 SHA512: a510fed0db4ad1aa2c3aa24c5a71faa5b85ca5d6066092de71bc1fec1c2b2f02d313afa95354d7378ba4481f13e81607cff1179e592096868803465c2e945a57 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-s3 Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12097 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-s3_0.10.0-rc_amd64.deb Size: 3043856 MD5sum: da4ad688feed254b43989a6a75c5945d SHA1: c9f0e47d748faab4d59e44b48bb1dcebdc388f6a SHA256: ebfddae2d7ce5c3974cf6c201d2b4fcc03db884bf0d892a43521dc31ccaf30c5 SHA512: e11155145782223c64a23a069482eb00ff78acd8a9df56ad6cf2fb898815cad4e2849b61855ec34b02476ef205796b0cddfefcfa29a36ea576aa508948f98430 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. tls: { // Certificate authority to authenticate the server. root_ca_certificate: "/home/user/certificates/minio/ca.pem", }, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { root_ca_certificate: "/home/user/certificates/minio/minica.pem", }, ``` . Here, the `root_ca_certificate` corresponds to the generated _minica.pem_ file. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { root_ca_certificate: "/home/user/certificates/minio_certs/minica.pem", }, } }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10890 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-s3_0.10.0-rc_arm64.deb Size: 2769628 MD5sum: eff8c4419df1201db82d12c75ae6495f SHA1: 7b72ca7101ba8380076ef66db7e77a73fa4f3c5c SHA256: 713736d04108f7156d6b8025ab25d47739d2d424b33140e11012fa3029b51245 SHA512: c4d2d7d6de9414043bbca5737f19db96da56de72ac552befa4b4d1de8a1519235dd009066823960cc967973d8ca95372864b9ca13f682e6609868d15a568e69d Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. tls: { // Certificate authority to authenticate the server. root_ca_certificate: "/home/user/certificates/minio/ca.pem", }, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { root_ca_certificate: "/home/user/certificates/minio/minica.pem", }, ``` . Here, the `root_ca_certificate` corresponds to the generated _minica.pem_ file. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { root_ca_certificate: "/home/user/certificates/minio_certs/minica.pem", }, } }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9674 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-s3_0.10.0-rc_armel.deb Size: 2425660 MD5sum: 46cc28bafec2e70272e0d19eea5e2034 SHA1: e6f7d2c2758b326d02a0bdadd29fb801cf97e8f8 SHA256: 5385516c87318b08f6f7c496d21d63db3d71fd79dd4f3958bb2e810227bdec54 SHA512: bd7fec80567ceae04b29650d16adbd351d0dac014b479c62dded38b58da02d0dc8c1aaaefb27d2307ded9020ac9b2e1a7ca93273ef54615e6688cb9b111612d0 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. tls: { // Certificate authority to authenticate the server. root_ca_certificate: "/home/user/certificates/minio/ca.pem", }, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { root_ca_certificate: "/home/user/certificates/minio/minica.pem", }, ``` . Here, the `root_ca_certificate` corresponds to the generated _minica.pem_ file. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { root_ca_certificate: "/home/user/certificates/minio_certs/minica.pem", }, } }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9542 Depends: zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-backend-s3_0.10.0-rc_armhf.deb Size: 2441424 MD5sum: e16f8e18281b0fea6472deab059dbc9e SHA1: 9a18777bd55f962cee87f9275777e05e8c92f03f SHA256: 9c58157ce92644558021b78a68a8adc016b56eeaf3fff3162b123be4402fb838 SHA512: 605004f99555822593afd272f4d8e2c50d20b24d049fbd0569d7a3fcc7ce2cb2fd9701fa2ad32b76cddceca6d148d12150a3223c4f2e56805fc0f061252e12b7 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. tls: { // Certificate authority to authenticate the server. root_ca_certificate: "/home/user/certificates/minio/ca.pem", }, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { root_ca_certificate: "/home/user/certificates/minio/minica.pem", }, ``` . Here, the `root_ca_certificate` corresponds to the generated _minica.pem_ file. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { root_ca_certificate: "/home/user/certificates/minio_certs/minica.pem", }, } }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-bridge-dds Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10899 Depends: libc6 (>= 2.29) Filename: ./0.10.0-rc/zenoh-bridge-dds_0.10.0-rc_amd64.deb Size: 3455680 MD5sum: 01c44059e6cf73ac1c751a0178398444 SHA1: ffb3376ac75995491d8b1d65ab44c2bd27cec339 SHA256: ea4cf37aec6f6bdeec1a30026509f16307d10d95b555e8ca677ff5c18978c864 SHA512: b8f58ac8879c9dc0850a214ca9a4315585830a1e839d042224b77f8cd3b8e57b062e2c94b3b37fd6596d4b635b92707ff223444fb72acce92250bef1ed681c19 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9530 Depends: libc6:arm64 (>= 2.31) Filename: ./0.10.0-rc/zenoh-bridge-dds_0.10.0-rc_arm64.deb Size: 3135084 MD5sum: 928b61d534e73492de48c571f841cb2f SHA1: fef0e4d4b6d7d0ba24de653bf279a8bb9cf41187 SHA256: e5f1a2be1f9a762c323033b2e73c0984f5a3d2d38cf637af913c8e14839c4a14 SHA512: 345971ea09db57569e2260dba2fca19697d995f689bbd5bd6065ea74bdb6cd4d5228d9ae64a2f245fbe921c458294997f4ba10e437280109881e0f9dd1f878f5 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9632 Depends: libc6:armel (>= 2.31) Filename: ./0.10.0-rc/zenoh-bridge-dds_0.10.0-rc_armel.deb Size: 3077192 MD5sum: 39d7a69f43909648fa02ddf7e05ee3dc SHA1: 1108e3aacaa4751265608003b817343486bafe67 SHA256: ef78a43d69c0b2a0f93b6df6118052af104b2fc65d60c02edd9dc6f3a3eaabf8 SHA512: 57e41ad740509c6035f586e37410d1555e3778798f33df52a5c7732a0bf3c617c40d750ebc9cd35a830054d96a0227aaa7a4044a9cca8943e5190d4b4830369e Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9164 Depends: libc6:armhf (>= 2.31) Filename: ./0.10.0-rc/zenoh-bridge-dds_0.10.0-rc_armhf.deb Size: 3082172 MD5sum: 8bf8cb4661544e87673e402d17020a41 SHA1: 330664c2d4799aae55db3bdd7d1e96995ff36022 SHA256: 24012aa34ecce88c02058fbf02b4fdd617b93d2e6bbb4d16a707dfeeb0055e21 SHA512: ab22d04c5010c447876ac510545776b2b1f6e23e0b5db75ec4c71cf7d3cc627af65d33adfc696e8b22bc29e8d624bbd114908aab12dda9d8e1cf715ba67e53a8 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-mqtt Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10028 Depends: libc6 (>= 2.29) Filename: ./0.10.0-rc/zenoh-bridge-mqtt_0.10.0-rc_amd64.deb Size: 3141324 MD5sum: 7f06a9f21d53805e0735b9b06f43f09a SHA1: a4963f2d1d115750c8b5e0649a5bebe19c31e103 SHA256: 4ca54fc05f432afbb089c638472e80b1a27409307aae2aa8a74122e677ca8b54 SHA512: 7771039441381e9a41e0dd2849714b550875cd39fd69ee306d22c502e8b3497185ed8f6fcb09df583de368c238bf92693fdc2bff9fe667d442c22f7187f2ab82 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8684 Depends: libc6:arm64 (>= 2.31) Filename: ./0.10.0-rc/zenoh-bridge-mqtt_0.10.0-rc_arm64.deb Size: 2845720 MD5sum: dba296f3356241858e390dc7b3a64ca5 SHA1: 83e88cf0f08bbf16386a0b389e1c33e81f2a77d1 SHA256: 831b25812a2f809c0d995122b83c384560afb351ee706354f01f3c8eda717e56 SHA512: 040ba5b5116eeb3ba1df9f94f45b8ff79c1aa4f68c7bd423e2020b8174d4b9a8324ea058dec37fff6cf65c0814dbcf9a25450af9d51a36ee8fd2e537ba935759 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-ros1 Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11276 Depends: libc6 (>= 2.29) Filename: ./0.10.0-rc/zenoh-bridge-ros1_0.10.0-rc_amd64.deb Size: 3391332 MD5sum: 52b53496825c9fe8350aeabc089834c9 SHA1: 0c7d629bc96287b7c54c26afc558fe1b5ea8f4be SHA256: a2aeb719c59c9ee30f4699a280db9eeef697da06e7c40acf23bbf88c02228bb4 SHA512: 0d3f41c2e6ab0d7e5ae0293a91728314ead9b94a97a584e0637ba21cf4a8125e2f7843a92a7f15a91bd97bba4b7cf777eff42b98d9b283c638dc9652ace14656 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9744 Depends: libc6:arm64 (>= 2.31) Filename: ./0.10.0-rc/zenoh-bridge-ros1_0.10.0-rc_arm64.deb Size: 3050764 MD5sum: 6f5a759c3bb4774135f14dda77c4ca09 SHA1: b4d88dcb18dc5d88304eab9626ce3af8474a50ee SHA256: 17db2d020af61bc553bc0c2e7616ec626ba6f86e748e77570064219e2ec04564 SHA512: a3be39ab1f55f06d2e244712b6241ac44f0a9c441c5a80635a42a6eb4a05f355bb7d91c45a800447526f8fade813db9da539dc871ca532b31c77ea96ba2e5eac Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9918 Depends: libc6:armel (>= 2.31) Filename: ./0.10.0-rc/zenoh-bridge-ros1_0.10.0-rc_armel.deb Size: 3033252 MD5sum: dec263191740bd70d4a11a29eb6ee025 SHA1: e73b98d1e7e31165f9fdb355cf33211b8ece7b0c SHA256: 4b9961c979e13015cff2eec98fcad662a85a2384cef24aa3c1579eb5ef065ca6 SHA512: 6038be04c879b391dc446bb2aaf8471f157a43563429d15cc1b058717ad563204dbed98395da0e48abfadd41714aea2ec5f9eca1c60df5bf507f204272e64538 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9658 Depends: libc6:armhf (>= 2.31) Filename: ./0.10.0-rc/zenoh-bridge-ros1_0.10.0-rc_armhf.deb Size: 3022472 MD5sum: e39734f898011bfe56429a2eebc53530 SHA1: 7a9b3a2495d3a82676604312194df26f1108952f SHA256: 09bc979e9d93e69d8f14fd4f1e479dc6a38241a80bbd8bdba46f4cd67442a528 SHA512: 3211e0c39cd52950ebcd116c69e5fe092e87b12743c31e631d83f65fa76a212fed88c2c5249ff5c2d85b71555f1d813b6806a265b4998dda36be893019aaaba3 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-cpp Architecture: x86_64 Version: 0.10.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 175 Filename: ./0.10.0-rc/zenoh-cpp-0.10.0.1.deb Size: 25072 MD5sum: 7e547a46dff4b8841100db16cda9b510 SHA1: a12e42b96fbf45675ba22f2f6045fa851023725d SHA256: faacd7427bf7f22e6441044ebb518dc0b058f264cab2c5ee359c65b172fd6640 SHA512: 7f98b28670fedb1ca073af755ec916cbe563fcf7821da4c720df311db33c974366c3f711f35b776c43a336877d27a851d65eac65ac9f2ed6f9d9ef37d83d717e Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: zenoh-plugin-dds Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4493 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-dds_0.10.0-rc_amd64.deb Size: 1379700 MD5sum: 7f1426d7e145690366499e862b2df140 SHA1: 4db854f1b1a2f3d03a8caa2ed5abfd295337c622 SHA256: 10dba9e7d027d83a1593faceaeb401220499947ccdb5637bb8598f9aa796cc50 SHA512: 0d6a728f13f2382b683ce4943507329bdf9bda1bec7174be2901f363d49b59d66ca5e09413e834464a6a8708fcd2d27a69fd716df9297c613ee84871a66de501 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS2) -- where it is used for communication between ROS2 nodes. . ## Robot Swarms and Edge Robotics As mentioned above, ROS2 has adopted DDS as the mechanism to exchange data between nodes within and potentially across a robot. That said, due to some of the very core assumptions at the foundations of the DDS wire-protocol, beside the fact that it leverages UDP/IP multicast for communication, it is not so straightforward to scale DDS communication over a WAN or across multiple LANs. Zenoh, on the other hand was designed since its inception to operate at Internet Scale. . ![zenoh-plugin-dds](http://zenoh.io/img/wiki/zenoh-plugin-dds.png) . Thus, the main motivations to have a **DDS plugin** for **Eclipse zenoh** are: . - Facilitate the interconnection of robot swarms. - Support use cases of edge robotics. - Give the possibility to use **zenoh**'s geo-distributed storage and query system to better manage robot's data. . As any plugin for Eclipse zenoh, it can be dynamically loaded by a zenoh router, at startup or at runtime. In addition, this project also provides a standalone version of this plugin as an executable binary named `zenoh-bridge-dds`. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-dds` (plugin library) and `zenoh-bridge-dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds ``` The **`zenoh-bridge-dds`** binary will be generated in the `target/release` sub-directory. . . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ### ROS2 package If you're a ROS2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:master` for the master branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ## For a quick test with ROS2 turtlesim Prerequisites: - A [ROS2 environment](http://docs.ros.org/en/galactic/Installation.html) (no matter the DDS implementation as soon as it implements the standard DDSI protocol - the default [Eclipse CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) being just fine) - The [turtlesim package](http://docs.ros.org/en/galactic/Tutorials/Turtlesim/Introducing-Turtlesim.html#install-turtlesim) . ### _1 host, 2 ROS domains_ For a quick test on a single host, you can run the `turtlesim_node` and the `turtle_teleop_key` on distinct ROS domains. As soon as you run 2 `zenoh-bridge-dds` (1 per domain) the `turtle_teleop_key` can drive the `turtlesim_node`. Here are the commands to run: - `ROS_DOMAIN_ID=1 ros2 run turtlesim turtlesim_node` - `ROS_DOMAIN_ID=2 ros2 run turtlesim turtle_teleop_key` - `./target/release/zenoh-bridge-dds -d 1` - `./target/release/zenoh-bridge-dds -d 2` . Notice that by default the 2 bridges will discover each other using UDP multicast. . ### _2 hosts, avoiding UDP multicast communication_ By default DDS (and thus ROS2) uses UDP multicast for discovery and publications. But on some networks, UDP multicast is not or badly supported. In such cases, deploying the `zenoh-bridge-dds` on both hosts will make it to: - limit the DDS discovery traffic, as detailled in [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) - route all the DDS publications made on UDP multicast by each node through the zenoh protocol that by default uses TCP. . Here are the commands to test this configuration with turtlesim: - on host 1: - `ROS_DOMAIN_ID=1 ros2 run turtlesim turtlesim_node` - `./target/release/zenoh-bridge-dds -d 1 -l tcp/0.0.0.0:7447` - on host 2: - `ROS_DOMAIN_ID=2 ros2 run turtlesim turtle_teleop_key` - `./target/release/zenoh-bridge-dds -d 2 -e tcp/:7447` - where `` is the IP of host 1 . Notice that to avoid unwanted direct DDS communication, 2 disctinct ROS domains are still used. . ### _2 hosts, with an intermediate zenoh router in the cloud_ In case your 2 hosts can't have a point-to-point communication, you could leverage a [zenoh router](https://github.com/eclipse-zenoh/zenoh#how-to-build-it) deployed in a cloud instance (any Linux VM will do the job). You just need to configure your cloud instanse with a public IP and authorize the TCP port **7447**. . :warning: the zenoh protocol is still under development leading to possible incompatibilities between the bridge and the router if their zenoh version differ. Please make sure you use a zenoh router built from a recent commit id from its `master` branch. . Here are the commands to test this configuration with turtlesim: - on cloud VM: - `zenohd` - on host 1: - `ros2 run turtlesim turtlesim_node` - `./target/release/zenoh-bridge-dds -e tcp/:7447` _where `` is the IP of your cloud instance_ - on host 2: - `ros2 run turtlesim turtle_teleop_key` - `./target/release/zenoh-bridge-dds -e tcp/:7447` _where `` is the IP of your cloud instance_ . Notice that there is no need to use distinct ROS domain here, since the 2 hosts are not supposed to directly communicate with each other. . ## More advanced usage for ROS2 ### _Full support of ROS graph and topic lists via the forward discovery mode_ By default the bridge doesn't route throught zenoh the DDS discovery traffic to the remote bridges. Meaning that, in case you use 2 **`zenoh-bridge-dds`** to interconnect 2 DDS domains, the DDS entities discovered in one domain won't be advertised in the other domain. Thus, the DDS data will be routed between the 2 domains only if matching readers and writers are declared in the 2 domains independently. . This default behaviour has an impact on ROS2 behaviour: on one side of the bridge the ROS graph might not reflect all the nodes from the other side of the bridge. The `ros2 topic list` command might not list all the topics declared on the other side. And the **ROS graph** is limited to the nodes in each domain. . But using the **`--fwd-discovery`** (or `-f`) option for all bridges make them behave differently: - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS2 nodes on each host. ### _Limiting the ROS2 topics, services, parameters or actions to be routed_ By default 2 zenoh bridges will route all ROS2 topics and services for which they detect a Writer on one side and a Reader on the other side. But you might want to avoid some topics and services to be routed by the bridge. . Starting `zenoh-bridge-dds` you can use the `--allow` argument to specify the subset of topics and services that will be routed by the bridge. This argument accepts a string wich is a regular expression that must match a substring of an allowed zenoh key (see details of [mapping of ROS2 names to zenoh keys](#mapping-ros2-names-to-zenoh-keys)). . Here are some examples of usage: | `--allow` value | allowed ROS2 communication | | :-- | :-- | | `/rosout` | `/rosout`| | `/rosout\|/turtle1/cmd_vel\|/turtle1/rotate_absolute` | `/rosout`
`/turtle1/cmd_vel`
`/turtle1/rotate_absolute` | | `/rosout\|/turtle1/` | `/rosout` and all `/turtle1` topics, services, parameters and actions | | `/turtle1/.*` | all topics and services with name containing `/turtle1/` | | `/turtle1/` | same: all topics, services, parameters and actions with name containing `/turtle1/` | | `rt/turtle1` | all topics with name containing `/turtle1` (no services, parameters or actions) | | `rq/turtle1\|/rr/turtle1` | all services and parameters with name containing `/turtle1` (no topics or actions) | | `rq/turtlesim/.*parameter\|/rr/turtlesim/.*parameter` | all parameters with name containing `/turtlesim` (no topics, services or actions) | | `rq/turtle1/.*/_action\|/rr/turtle1/.*/_action` | all actions with name containing `/turtle1` (no topics, services or parameters) | . ### _Running several robots without changing the ROS2 configuration_ If you run similar robots in the same network, they will by default all us the same DDS topics, leading to interferences in their operations. A simple way to address this issue using the zenoh bridge is to: - deploy 1 zenoh bridge per robot - have each bridge started with the `--scope "/"` argument, each robot having its own id. - make sure each robot cannot directly communicate via DDS with another robot by setting a distinct domain per robot, or configuring its network interface to not route UDP multicast outside the host. . Using the `--scope` option, a prefix is added to each zenoh key published/subscribed by the bridge (more details in [mapping of ROS2 names to zenoh keys](#mapping-ros2-names-to-zenoh-keys)). To interact with a robot, a remote ROS2 application must use a zenoh bridge configured with the same scope than the robot. . ### _Closer integration of ROS2 with zenoh_ As you understood, using the zenoh bridge, each ROS2 publications and subscriptions are mapped to a zenoh key. Therefore, its relatively easy to develop an application using one of the [zenoh APIs](https://zenoh.io/docs/apis/apis/) to interact with one or more robot at the same time. . See in details how to achieve that in [this blog](https://zenoh.io/blog/2021-04-28-ros2-integration/). . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . The `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@/service//dds` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//dds/version` : the bridge version - `@/service//dds/config` : the bridge configuration - `@/service//dds/participant//reader//` : a discovered DDS reader on `` - `@/service//dds/participant//writer//` : a discovered DDS reader on `` - `@/service//dds/route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@/service//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@/service/**/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@/service/**/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@/service/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . Whether it's built as a library or as a standalone executable, the **zenoh bridge for DDS** do the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - it behaves as described [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS2 names to zenoh keys_ The mapping from ROS2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4005 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-dds_0.10.0-rc_arm64.deb Size: 1226436 MD5sum: bf73481c8f88b053eaaba2d598272212 SHA1: 75ae7d5fca6392db125eb14f11173c467cd10049 SHA256: efc316c241f0908999350f2a811c84c4ec04afa2fa5a6fa38c07e205b0ae2667 SHA512: f8838d3aafea1a1bb38d15e1dbc6ccf4037f4139a202f5913f1e2c4cbc88442fa3ae62807b2c224610a468d1905236eb013adc35abe2f8c8b7bc0af52396b1ec Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS2) -- where it is used for communication between ROS2 nodes. . ## Robot Swarms and Edge Robotics As mentioned above, ROS2 has adopted DDS as the mechanism to exchange data between nodes within and potentially across a robot. That said, due to some of the very core assumptions at the foundations of the DDS wire-protocol, beside the fact that it leverages UDP/IP multicast for communication, it is not so straightforward to scale DDS communication over a WAN or across multiple LANs. Zenoh, on the other hand was designed since its inception to operate at Internet Scale. . ![zenoh-plugin-dds](http://zenoh.io/img/wiki/zenoh-plugin-dds.png) . Thus, the main motivations to have a **DDS plugin** for **Eclipse zenoh** are: . - Facilitate the interconnection of robot swarms. - Support use cases of edge robotics. - Give the possibility to use **zenoh**'s geo-distributed storage and query system to better manage robot's data. . As any plugin for Eclipse zenoh, it can be dynamically loaded by a zenoh router, at startup or at runtime. In addition, this project also provides a standalone version of this plugin as an executable binary named `zenoh-bridge-dds`. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-dds` (plugin library) and `zenoh-bridge-dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds ``` The **`zenoh-bridge-dds`** binary will be generated in the `target/release` sub-directory. . . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ### ROS2 package If you're a ROS2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:master` for the master branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ## For a quick test with ROS2 turtlesim Prerequisites: - A [ROS2 environment](http://docs.ros.org/en/galactic/Installation.html) (no matter the DDS implementation as soon as it implements the standard DDSI protocol - the default [Eclipse CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) being just fine) - The [turtlesim package](http://docs.ros.org/en/galactic/Tutorials/Turtlesim/Introducing-Turtlesim.html#install-turtlesim) . ### _1 host, 2 ROS domains_ For a quick test on a single host, you can run the `turtlesim_node` and the `turtle_teleop_key` on distinct ROS domains. As soon as you run 2 `zenoh-bridge-dds` (1 per domain) the `turtle_teleop_key` can drive the `turtlesim_node`. Here are the commands to run: - `ROS_DOMAIN_ID=1 ros2 run turtlesim turtlesim_node` - `ROS_DOMAIN_ID=2 ros2 run turtlesim turtle_teleop_key` - `./target/release/zenoh-bridge-dds -d 1` - `./target/release/zenoh-bridge-dds -d 2` . Notice that by default the 2 bridges will discover each other using UDP multicast. . ### _2 hosts, avoiding UDP multicast communication_ By default DDS (and thus ROS2) uses UDP multicast for discovery and publications. But on some networks, UDP multicast is not or badly supported. In such cases, deploying the `zenoh-bridge-dds` on both hosts will make it to: - limit the DDS discovery traffic, as detailled in [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) - route all the DDS publications made on UDP multicast by each node through the zenoh protocol that by default uses TCP. . Here are the commands to test this configuration with turtlesim: - on host 1: - `ROS_DOMAIN_ID=1 ros2 run turtlesim turtlesim_node` - `./target/release/zenoh-bridge-dds -d 1 -l tcp/0.0.0.0:7447` - on host 2: - `ROS_DOMAIN_ID=2 ros2 run turtlesim turtle_teleop_key` - `./target/release/zenoh-bridge-dds -d 2 -e tcp/:7447` - where `` is the IP of host 1 . Notice that to avoid unwanted direct DDS communication, 2 disctinct ROS domains are still used. . ### _2 hosts, with an intermediate zenoh router in the cloud_ In case your 2 hosts can't have a point-to-point communication, you could leverage a [zenoh router](https://github.com/eclipse-zenoh/zenoh#how-to-build-it) deployed in a cloud instance (any Linux VM will do the job). You just need to configure your cloud instanse with a public IP and authorize the TCP port **7447**. . :warning: the zenoh protocol is still under development leading to possible incompatibilities between the bridge and the router if their zenoh version differ. Please make sure you use a zenoh router built from a recent commit id from its `master` branch. . Here are the commands to test this configuration with turtlesim: - on cloud VM: - `zenohd` - on host 1: - `ros2 run turtlesim turtlesim_node` - `./target/release/zenoh-bridge-dds -e tcp/:7447` _where `` is the IP of your cloud instance_ - on host 2: - `ros2 run turtlesim turtle_teleop_key` - `./target/release/zenoh-bridge-dds -e tcp/:7447` _where `` is the IP of your cloud instance_ . Notice that there is no need to use distinct ROS domain here, since the 2 hosts are not supposed to directly communicate with each other. . ## More advanced usage for ROS2 ### _Full support of ROS graph and topic lists via the forward discovery mode_ By default the bridge doesn't route throught zenoh the DDS discovery traffic to the remote bridges. Meaning that, in case you use 2 **`zenoh-bridge-dds`** to interconnect 2 DDS domains, the DDS entities discovered in one domain won't be advertised in the other domain. Thus, the DDS data will be routed between the 2 domains only if matching readers and writers are declared in the 2 domains independently. . This default behaviour has an impact on ROS2 behaviour: on one side of the bridge the ROS graph might not reflect all the nodes from the other side of the bridge. The `ros2 topic list` command might not list all the topics declared on the other side. And the **ROS graph** is limited to the nodes in each domain. . But using the **`--fwd-discovery`** (or `-f`) option for all bridges make them behave differently: - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS2 nodes on each host. ### _Limiting the ROS2 topics, services, parameters or actions to be routed_ By default 2 zenoh bridges will route all ROS2 topics and services for which they detect a Writer on one side and a Reader on the other side. But you might want to avoid some topics and services to be routed by the bridge. . Starting `zenoh-bridge-dds` you can use the `--allow` argument to specify the subset of topics and services that will be routed by the bridge. This argument accepts a string wich is a regular expression that must match a substring of an allowed zenoh key (see details of [mapping of ROS2 names to zenoh keys](#mapping-ros2-names-to-zenoh-keys)). . Here are some examples of usage: | `--allow` value | allowed ROS2 communication | | :-- | :-- | | `/rosout` | `/rosout`| | `/rosout\|/turtle1/cmd_vel\|/turtle1/rotate_absolute` | `/rosout`
`/turtle1/cmd_vel`
`/turtle1/rotate_absolute` | | `/rosout\|/turtle1/` | `/rosout` and all `/turtle1` topics, services, parameters and actions | | `/turtle1/.*` | all topics and services with name containing `/turtle1/` | | `/turtle1/` | same: all topics, services, parameters and actions with name containing `/turtle1/` | | `rt/turtle1` | all topics with name containing `/turtle1` (no services, parameters or actions) | | `rq/turtle1\|/rr/turtle1` | all services and parameters with name containing `/turtle1` (no topics or actions) | | `rq/turtlesim/.*parameter\|/rr/turtlesim/.*parameter` | all parameters with name containing `/turtlesim` (no topics, services or actions) | | `rq/turtle1/.*/_action\|/rr/turtle1/.*/_action` | all actions with name containing `/turtle1` (no topics, services or parameters) | . ### _Running several robots without changing the ROS2 configuration_ If you run similar robots in the same network, they will by default all us the same DDS topics, leading to interferences in their operations. A simple way to address this issue using the zenoh bridge is to: - deploy 1 zenoh bridge per robot - have each bridge started with the `--scope "/"` argument, each robot having its own id. - make sure each robot cannot directly communicate via DDS with another robot by setting a distinct domain per robot, or configuring its network interface to not route UDP multicast outside the host. . Using the `--scope` option, a prefix is added to each zenoh key published/subscribed by the bridge (more details in [mapping of ROS2 names to zenoh keys](#mapping-ros2-names-to-zenoh-keys)). To interact with a robot, a remote ROS2 application must use a zenoh bridge configured with the same scope than the robot. . ### _Closer integration of ROS2 with zenoh_ As you understood, using the zenoh bridge, each ROS2 publications and subscriptions are mapped to a zenoh key. Therefore, its relatively easy to develop an application using one of the [zenoh APIs](https://zenoh.io/docs/apis/apis/) to interact with one or more robot at the same time. . See in details how to achieve that in [this blog](https://zenoh.io/blog/2021-04-28-ros2-integration/). . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . The `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@/service//dds` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//dds/version` : the bridge version - `@/service//dds/config` : the bridge configuration - `@/service//dds/participant//reader//` : a discovered DDS reader on `` - `@/service//dds/participant//writer//` : a discovered DDS reader on `` - `@/service//dds/route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@/service//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@/service/**/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@/service/**/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@/service/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . Whether it's built as a library or as a standalone executable, the **zenoh bridge for DDS** do the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - it behaves as described [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS2 names to zenoh keys_ The mapping from ROS2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3888 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-dds_0.10.0-rc_armel.deb Size: 1208656 MD5sum: 49e5d71d368745b6791548e65e151d66 SHA1: 1f5122443e032578fecd13864856ff8fb92e16eb SHA256: 6e1f714b2ecf9bfc1b333b3c074e19a76fa1b96d60f96ba6690a0ce97d3dc0e1 SHA512: c58557c8d72760fe1581c34d02de966e925f859984b91887c82c13d2881e892eee2975f25186c99e80cf2d35025a004098938cf59a148399a05e715a8bbe9f81 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS2) -- where it is used for communication between ROS2 nodes. . ## Robot Swarms and Edge Robotics As mentioned above, ROS2 has adopted DDS as the mechanism to exchange data between nodes within and potentially across a robot. That said, due to some of the very core assumptions at the foundations of the DDS wire-protocol, beside the fact that it leverages UDP/IP multicast for communication, it is not so straightforward to scale DDS communication over a WAN or across multiple LANs. Zenoh, on the other hand was designed since its inception to operate at Internet Scale. . ![zenoh-plugin-dds](http://zenoh.io/img/wiki/zenoh-plugin-dds.png) . Thus, the main motivations to have a **DDS plugin** for **Eclipse zenoh** are: . - Facilitate the interconnection of robot swarms. - Support use cases of edge robotics. - Give the possibility to use **zenoh**'s geo-distributed storage and query system to better manage robot's data. . As any plugin for Eclipse zenoh, it can be dynamically loaded by a zenoh router, at startup or at runtime. In addition, this project also provides a standalone version of this plugin as an executable binary named `zenoh-bridge-dds`. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-dds` (plugin library) and `zenoh-bridge-dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds ``` The **`zenoh-bridge-dds`** binary will be generated in the `target/release` sub-directory. . . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ### ROS2 package If you're a ROS2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:master` for the master branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ## For a quick test with ROS2 turtlesim Prerequisites: - A [ROS2 environment](http://docs.ros.org/en/galactic/Installation.html) (no matter the DDS implementation as soon as it implements the standard DDSI protocol - the default [Eclipse CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) being just fine) - The [turtlesim package](http://docs.ros.org/en/galactic/Tutorials/Turtlesim/Introducing-Turtlesim.html#install-turtlesim) . ### _1 host, 2 ROS domains_ For a quick test on a single host, you can run the `turtlesim_node` and the `turtle_teleop_key` on distinct ROS domains. As soon as you run 2 `zenoh-bridge-dds` (1 per domain) the `turtle_teleop_key` can drive the `turtlesim_node`. Here are the commands to run: - `ROS_DOMAIN_ID=1 ros2 run turtlesim turtlesim_node` - `ROS_DOMAIN_ID=2 ros2 run turtlesim turtle_teleop_key` - `./target/release/zenoh-bridge-dds -d 1` - `./target/release/zenoh-bridge-dds -d 2` . Notice that by default the 2 bridges will discover each other using UDP multicast. . ### _2 hosts, avoiding UDP multicast communication_ By default DDS (and thus ROS2) uses UDP multicast for discovery and publications. But on some networks, UDP multicast is not or badly supported. In such cases, deploying the `zenoh-bridge-dds` on both hosts will make it to: - limit the DDS discovery traffic, as detailled in [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) - route all the DDS publications made on UDP multicast by each node through the zenoh protocol that by default uses TCP. . Here are the commands to test this configuration with turtlesim: - on host 1: - `ROS_DOMAIN_ID=1 ros2 run turtlesim turtlesim_node` - `./target/release/zenoh-bridge-dds -d 1 -l tcp/0.0.0.0:7447` - on host 2: - `ROS_DOMAIN_ID=2 ros2 run turtlesim turtle_teleop_key` - `./target/release/zenoh-bridge-dds -d 2 -e tcp/:7447` - where `` is the IP of host 1 . Notice that to avoid unwanted direct DDS communication, 2 disctinct ROS domains are still used. . ### _2 hosts, with an intermediate zenoh router in the cloud_ In case your 2 hosts can't have a point-to-point communication, you could leverage a [zenoh router](https://github.com/eclipse-zenoh/zenoh#how-to-build-it) deployed in a cloud instance (any Linux VM will do the job). You just need to configure your cloud instanse with a public IP and authorize the TCP port **7447**. . :warning: the zenoh protocol is still under development leading to possible incompatibilities between the bridge and the router if their zenoh version differ. Please make sure you use a zenoh router built from a recent commit id from its `master` branch. . Here are the commands to test this configuration with turtlesim: - on cloud VM: - `zenohd` - on host 1: - `ros2 run turtlesim turtlesim_node` - `./target/release/zenoh-bridge-dds -e tcp/:7447` _where `` is the IP of your cloud instance_ - on host 2: - `ros2 run turtlesim turtle_teleop_key` - `./target/release/zenoh-bridge-dds -e tcp/:7447` _where `` is the IP of your cloud instance_ . Notice that there is no need to use distinct ROS domain here, since the 2 hosts are not supposed to directly communicate with each other. . ## More advanced usage for ROS2 ### _Full support of ROS graph and topic lists via the forward discovery mode_ By default the bridge doesn't route throught zenoh the DDS discovery traffic to the remote bridges. Meaning that, in case you use 2 **`zenoh-bridge-dds`** to interconnect 2 DDS domains, the DDS entities discovered in one domain won't be advertised in the other domain. Thus, the DDS data will be routed between the 2 domains only if matching readers and writers are declared in the 2 domains independently. . This default behaviour has an impact on ROS2 behaviour: on one side of the bridge the ROS graph might not reflect all the nodes from the other side of the bridge. The `ros2 topic list` command might not list all the topics declared on the other side. And the **ROS graph** is limited to the nodes in each domain. . But using the **`--fwd-discovery`** (or `-f`) option for all bridges make them behave differently: - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS2 nodes on each host. ### _Limiting the ROS2 topics, services, parameters or actions to be routed_ By default 2 zenoh bridges will route all ROS2 topics and services for which they detect a Writer on one side and a Reader on the other side. But you might want to avoid some topics and services to be routed by the bridge. . Starting `zenoh-bridge-dds` you can use the `--allow` argument to specify the subset of topics and services that will be routed by the bridge. This argument accepts a string wich is a regular expression that must match a substring of an allowed zenoh key (see details of [mapping of ROS2 names to zenoh keys](#mapping-ros2-names-to-zenoh-keys)). . Here are some examples of usage: | `--allow` value | allowed ROS2 communication | | :-- | :-- | | `/rosout` | `/rosout`| | `/rosout\|/turtle1/cmd_vel\|/turtle1/rotate_absolute` | `/rosout`
`/turtle1/cmd_vel`
`/turtle1/rotate_absolute` | | `/rosout\|/turtle1/` | `/rosout` and all `/turtle1` topics, services, parameters and actions | | `/turtle1/.*` | all topics and services with name containing `/turtle1/` | | `/turtle1/` | same: all topics, services, parameters and actions with name containing `/turtle1/` | | `rt/turtle1` | all topics with name containing `/turtle1` (no services, parameters or actions) | | `rq/turtle1\|/rr/turtle1` | all services and parameters with name containing `/turtle1` (no topics or actions) | | `rq/turtlesim/.*parameter\|/rr/turtlesim/.*parameter` | all parameters with name containing `/turtlesim` (no topics, services or actions) | | `rq/turtle1/.*/_action\|/rr/turtle1/.*/_action` | all actions with name containing `/turtle1` (no topics, services or parameters) | . ### _Running several robots without changing the ROS2 configuration_ If you run similar robots in the same network, they will by default all us the same DDS topics, leading to interferences in their operations. A simple way to address this issue using the zenoh bridge is to: - deploy 1 zenoh bridge per robot - have each bridge started with the `--scope "/"` argument, each robot having its own id. - make sure each robot cannot directly communicate via DDS with another robot by setting a distinct domain per robot, or configuring its network interface to not route UDP multicast outside the host. . Using the `--scope` option, a prefix is added to each zenoh key published/subscribed by the bridge (more details in [mapping of ROS2 names to zenoh keys](#mapping-ros2-names-to-zenoh-keys)). To interact with a robot, a remote ROS2 application must use a zenoh bridge configured with the same scope than the robot. . ### _Closer integration of ROS2 with zenoh_ As you understood, using the zenoh bridge, each ROS2 publications and subscriptions are mapped to a zenoh key. Therefore, its relatively easy to develop an application using one of the [zenoh APIs](https://zenoh.io/docs/apis/apis/) to interact with one or more robot at the same time. . See in details how to achieve that in [this blog](https://zenoh.io/blog/2021-04-28-ros2-integration/). . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . The `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@/service//dds` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//dds/version` : the bridge version - `@/service//dds/config` : the bridge configuration - `@/service//dds/participant//reader//` : a discovered DDS reader on `` - `@/service//dds/participant//writer//` : a discovered DDS reader on `` - `@/service//dds/route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@/service//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@/service/**/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@/service/**/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@/service/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . Whether it's built as a library or as a standalone executable, the **zenoh bridge for DDS** do the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - it behaves as described [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS2 names to zenoh keys_ The mapping from ROS2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3572 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-dds_0.10.0-rc_armhf.deb Size: 1211856 MD5sum: f4fe8ab19b208d28623176771754b4fe SHA1: 53bb3cec4ee93056decdc5aad60fae935de1c274 SHA256: 88468db4f5cfa0f8789baa07e1c577d9ea314cc94f1f36419165f24e710546bc SHA512: 2c34367fdf5a9448ea4a2b32c2296fa19015d9f889f4e2ed9b8c0306e15d7af963b6621cf18ad8ff04e20ee025c55652473ae010d6aea3120fd393898af61880 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS2) -- where it is used for communication between ROS2 nodes. . ## Robot Swarms and Edge Robotics As mentioned above, ROS2 has adopted DDS as the mechanism to exchange data between nodes within and potentially across a robot. That said, due to some of the very core assumptions at the foundations of the DDS wire-protocol, beside the fact that it leverages UDP/IP multicast for communication, it is not so straightforward to scale DDS communication over a WAN or across multiple LANs. Zenoh, on the other hand was designed since its inception to operate at Internet Scale. . ![zenoh-plugin-dds](http://zenoh.io/img/wiki/zenoh-plugin-dds.png) . Thus, the main motivations to have a **DDS plugin** for **Eclipse zenoh** are: . - Facilitate the interconnection of robot swarms. - Support use cases of edge robotics. - Give the possibility to use **zenoh**'s geo-distributed storage and query system to better manage robot's data. . As any plugin for Eclipse zenoh, it can be dynamically loaded by a zenoh router, at startup or at runtime. In addition, this project also provides a standalone version of this plugin as an executable binary named `zenoh-bridge-dds`. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-dds` (plugin library) and `zenoh-bridge-dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds ``` The **`zenoh-bridge-dds`** binary will be generated in the `target/release` sub-directory. . . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ### ROS2 package If you're a ROS2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:master` for the master branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ## For a quick test with ROS2 turtlesim Prerequisites: - A [ROS2 environment](http://docs.ros.org/en/galactic/Installation.html) (no matter the DDS implementation as soon as it implements the standard DDSI protocol - the default [Eclipse CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) being just fine) - The [turtlesim package](http://docs.ros.org/en/galactic/Tutorials/Turtlesim/Introducing-Turtlesim.html#install-turtlesim) . ### _1 host, 2 ROS domains_ For a quick test on a single host, you can run the `turtlesim_node` and the `turtle_teleop_key` on distinct ROS domains. As soon as you run 2 `zenoh-bridge-dds` (1 per domain) the `turtle_teleop_key` can drive the `turtlesim_node`. Here are the commands to run: - `ROS_DOMAIN_ID=1 ros2 run turtlesim turtlesim_node` - `ROS_DOMAIN_ID=2 ros2 run turtlesim turtle_teleop_key` - `./target/release/zenoh-bridge-dds -d 1` - `./target/release/zenoh-bridge-dds -d 2` . Notice that by default the 2 bridges will discover each other using UDP multicast. . ### _2 hosts, avoiding UDP multicast communication_ By default DDS (and thus ROS2) uses UDP multicast for discovery and publications. But on some networks, UDP multicast is not or badly supported. In such cases, deploying the `zenoh-bridge-dds` on both hosts will make it to: - limit the DDS discovery traffic, as detailled in [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) - route all the DDS publications made on UDP multicast by each node through the zenoh protocol that by default uses TCP. . Here are the commands to test this configuration with turtlesim: - on host 1: - `ROS_DOMAIN_ID=1 ros2 run turtlesim turtlesim_node` - `./target/release/zenoh-bridge-dds -d 1 -l tcp/0.0.0.0:7447` - on host 2: - `ROS_DOMAIN_ID=2 ros2 run turtlesim turtle_teleop_key` - `./target/release/zenoh-bridge-dds -d 2 -e tcp/:7447` - where `` is the IP of host 1 . Notice that to avoid unwanted direct DDS communication, 2 disctinct ROS domains are still used. . ### _2 hosts, with an intermediate zenoh router in the cloud_ In case your 2 hosts can't have a point-to-point communication, you could leverage a [zenoh router](https://github.com/eclipse-zenoh/zenoh#how-to-build-it) deployed in a cloud instance (any Linux VM will do the job). You just need to configure your cloud instanse with a public IP and authorize the TCP port **7447**. . :warning: the zenoh protocol is still under development leading to possible incompatibilities between the bridge and the router if their zenoh version differ. Please make sure you use a zenoh router built from a recent commit id from its `master` branch. . Here are the commands to test this configuration with turtlesim: - on cloud VM: - `zenohd` - on host 1: - `ros2 run turtlesim turtlesim_node` - `./target/release/zenoh-bridge-dds -e tcp/:7447` _where `` is the IP of your cloud instance_ - on host 2: - `ros2 run turtlesim turtle_teleop_key` - `./target/release/zenoh-bridge-dds -e tcp/:7447` _where `` is the IP of your cloud instance_ . Notice that there is no need to use distinct ROS domain here, since the 2 hosts are not supposed to directly communicate with each other. . ## More advanced usage for ROS2 ### _Full support of ROS graph and topic lists via the forward discovery mode_ By default the bridge doesn't route throught zenoh the DDS discovery traffic to the remote bridges. Meaning that, in case you use 2 **`zenoh-bridge-dds`** to interconnect 2 DDS domains, the DDS entities discovered in one domain won't be advertised in the other domain. Thus, the DDS data will be routed between the 2 domains only if matching readers and writers are declared in the 2 domains independently. . This default behaviour has an impact on ROS2 behaviour: on one side of the bridge the ROS graph might not reflect all the nodes from the other side of the bridge. The `ros2 topic list` command might not list all the topics declared on the other side. And the **ROS graph** is limited to the nodes in each domain. . But using the **`--fwd-discovery`** (or `-f`) option for all bridges make them behave differently: - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS2 nodes on each host. ### _Limiting the ROS2 topics, services, parameters or actions to be routed_ By default 2 zenoh bridges will route all ROS2 topics and services for which they detect a Writer on one side and a Reader on the other side. But you might want to avoid some topics and services to be routed by the bridge. . Starting `zenoh-bridge-dds` you can use the `--allow` argument to specify the subset of topics and services that will be routed by the bridge. This argument accepts a string wich is a regular expression that must match a substring of an allowed zenoh key (see details of [mapping of ROS2 names to zenoh keys](#mapping-ros2-names-to-zenoh-keys)). . Here are some examples of usage: | `--allow` value | allowed ROS2 communication | | :-- | :-- | | `/rosout` | `/rosout`| | `/rosout\|/turtle1/cmd_vel\|/turtle1/rotate_absolute` | `/rosout`
`/turtle1/cmd_vel`
`/turtle1/rotate_absolute` | | `/rosout\|/turtle1/` | `/rosout` and all `/turtle1` topics, services, parameters and actions | | `/turtle1/.*` | all topics and services with name containing `/turtle1/` | | `/turtle1/` | same: all topics, services, parameters and actions with name containing `/turtle1/` | | `rt/turtle1` | all topics with name containing `/turtle1` (no services, parameters or actions) | | `rq/turtle1\|/rr/turtle1` | all services and parameters with name containing `/turtle1` (no topics or actions) | | `rq/turtlesim/.*parameter\|/rr/turtlesim/.*parameter` | all parameters with name containing `/turtlesim` (no topics, services or actions) | | `rq/turtle1/.*/_action\|/rr/turtle1/.*/_action` | all actions with name containing `/turtle1` (no topics, services or parameters) | . ### _Running several robots without changing the ROS2 configuration_ If you run similar robots in the same network, they will by default all us the same DDS topics, leading to interferences in their operations. A simple way to address this issue using the zenoh bridge is to: - deploy 1 zenoh bridge per robot - have each bridge started with the `--scope "/"` argument, each robot having its own id. - make sure each robot cannot directly communicate via DDS with another robot by setting a distinct domain per robot, or configuring its network interface to not route UDP multicast outside the host. . Using the `--scope` option, a prefix is added to each zenoh key published/subscribed by the bridge (more details in [mapping of ROS2 names to zenoh keys](#mapping-ros2-names-to-zenoh-keys)). To interact with a robot, a remote ROS2 application must use a zenoh bridge configured with the same scope than the robot. . ### _Closer integration of ROS2 with zenoh_ As you understood, using the zenoh bridge, each ROS2 publications and subscriptions are mapped to a zenoh key. Therefore, its relatively easy to develop an application using one of the [zenoh APIs](https://zenoh.io/docs/apis/apis/) to interact with one or more robot at the same time. . See in details how to achieve that in [this blog](https://zenoh.io/blog/2021-04-28-ros2-integration/). . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . The `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@/service//dds` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//dds/version` : the bridge version - `@/service//dds/config` : the bridge configuration - `@/service//dds/participant//reader//` : a discovered DDS reader on `` - `@/service//dds/participant//writer//` : a discovered DDS reader on `` - `@/service//dds/route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@/service//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@/service/**/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@/service/**/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@/service/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . Whether it's built as a library or as a standalone executable, the **zenoh bridge for DDS** do the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - it behaves as described [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS2 names to zenoh keys_ The mapping from ROS2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-mqtt Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3590 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-mqtt_0.10.0-rc_amd64.deb Size: 1040636 MD5sum: 460d01843e56597e299f39bc520d1e45 SHA1: 13119bbb2f799de34ac220ae68b6185bce3cc094 SHA256: 81775c113d4ffef98e6b1912e9a8ce269e76a29a4ffb5d9ac684921c9fc4005b SHA512: 8ad44331374c6663a83eb56ff4ad5c8212e46426bc966d95bd11a2bdaff2ac6c7c52b90af1083022ddeb34feeb4ec64644ab247ebcfefd52199597d62c181cc2 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:master` for the master branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt ``` . You can then choose between building the zenoh bridge for MQTT: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-mqtt ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-mqtt ``` The **`zenoh-bridge-mqtt`** binary will be generated in the `target/release` sub-directory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3134 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-mqtt_0.10.0-rc_arm64.deb Size: 913732 MD5sum: 5ca7b918cac0a2589c1abb40ae291912 SHA1: d9ba6ef82b471137467b3b4c5457ebf54393217f SHA256: f58cdc7879aae4e56ec1aed61bbe88979c287cfa1747ed09d4cd283d23f9ffc6 SHA512: b899ecb24830a7031696dfc4e11519a3a7e771ca39e8ca9f7a21ef1dc07d66bab7fd922ea723c6cad577bddae5e30c0b5d62a927e871918acab8a53764d3f8cc Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:master` for the master branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt ``` . You can then choose between building the zenoh bridge for MQTT: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-mqtt ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-mqtt ``` The **`zenoh-bridge-mqtt`** binary will be generated in the `target/release` sub-directory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-rest Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3624 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-rest_0.10.0-rc_amd64.deb Size: 1061712 MD5sum: 2dd440e445f13d160db20c0edebbdc87 SHA1: 6d8d3e2491310c22ffe47e41e3d8e402eba2ba5e SHA256: 98d5b512ed5dce0cc0ee292b58965c2528d6262ea80f9b4189f9d6040eab6b49 SHA512: 7719ac74f2bdaffe49a570be20c8fc2c8e2bbcffb13ce09991497a40e9ac592fb88d7b7a738429da3996bc68499a4a3db26ea3a2be24507d081da5227b2248ae Homepage: http://zenoh.io Description: The zenoh REST plugin . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3188 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-rest_0.10.0-rc_arm64.deb Size: 939828 MD5sum: ba985bdca2c34a77ef855b64fce36863 SHA1: 74fde077bd6422bacc6e599ea4eb5eeb4c47bdf6 SHA256: f94adb87cf2690307b14a066f813f50a53084d0ac7eb430cd09b0d5d196b3396 SHA512: e2b8ef965a9c4bbd7d97b4269758366f8577301de0f51627b38f60244d8112ce8cbf95e64cf66fd9782cfd5019622e70dca99cd3c41d720b6f1ec9cd1d39a83b Homepage: http://zenoh.io Description: The zenoh REST plugin . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3143 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-rest_0.10.0-rc_armel.deb Size: 945940 MD5sum: 97f6b7aaaf905e01e2c7198ba6acfad5 SHA1: 69bb5f7e5c77c64955b4acca896c3ed5341a7ea9 SHA256: b4720b92fec65889e8e13d6ae5bfe98fca56f5e7d1d9b243bc2b9b979461499e SHA512: 984bab735ad575dc3e25d4f138e246160e068524285408f9354cd84b83b7da028e7eaaa30bb39cbfa5e8ac4409ffc253ba07a52af55697b48ea3ed769010b8c9 Homepage: http://zenoh.io Description: The zenoh REST plugin . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3063 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-rest_0.10.0-rc_armhf.deb Size: 934856 MD5sum: 924f7d269acbd40819bbc07a5f196463 SHA1: e2ad0d5fea140b4ba6dfb1afba9bca19888422bb SHA256: 9c97730a2ec5f990894709c04a91c2263d040da56c0144cb5a51b46d4ec46a9a SHA512: 1459ca27680de6df7ec710d9dd4720f0cc2cccd85c86035242bc585fcb5fb0cbf479e1684efc3d7929cf98304c6074c4ca8598ec3e2c833e07942eea349e9930 Homepage: http://zenoh.io Description: The zenoh REST plugin . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-ros1 Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5604 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-ros1_0.10.0-rc_amd64.deb Size: 1673276 MD5sum: 62169e0c1c6325cfa4254f1ab89c9f5b SHA1: 718da84038cb5eb443851081ecd6ecf484f457bc SHA256: 3447824c9eec4616f7cea3d73526887f0260b76e33acf262bf42a48f7412769c SHA512: 92a2debe68bf5f8dd2b3f629309d7424443d04de8fc6c83836b589228ff7d8a49a8d3c15f192af808a97969a204dd6f991812094b5637fdefbdf6cb7da096a94 Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 ``` . > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros1` (plugin library) and `zenoh-bridge-ros1` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for ROS1: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros1 ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros1 ``` The **`zenoh-bridge-ros1`** binary will be generated in the `target/release` sub-directory. . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:master` for the master branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5004 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-ros1_0.10.0-rc_arm64.deb Size: 1520208 MD5sum: 0cbae8bdc459e9263b3f91c680ed8fd5 SHA1: 7d6189d28f01772a91695d24a333c32aec0d8dd5 SHA256: a1fc0b0c41d1ac922b958acbf0f7555d1823070a00351e14e3a7f602cd9014c2 SHA512: b53e13f792b922e3a072c66e4d12df9f25680d2c5831aaddb71300c36f59565058b06963f9fee768d2232542cdf081516eaa6ec44a47bfacc029b4e004e91bc9 Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 ``` . > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros1` (plugin library) and `zenoh-bridge-ros1` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for ROS1: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros1 ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros1 ``` The **`zenoh-bridge-ros1`** binary will be generated in the `target/release` sub-directory. . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:master` for the master branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5107 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-ros1_0.10.0-rc_armel.deb Size: 1559456 MD5sum: b98409def1d5c5a5a8e387226a49ece9 SHA1: ea52b0aca31f1599d1216547373b618ec1affef5 SHA256: d0b7246a56cdfb7b5a5ebe9307080dba489261fd9165ab5c99c022f627f812f0 SHA512: dfdc136c9084f7d51d20f8d66753b9826e8d759f0ef88dc91d4c5e5f807188a0b7312e47814b82697356a0e5e7e6b5aea92db03d85162f8ec668af264a55a16a Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 ``` . > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros1` (plugin library) and `zenoh-bridge-ros1` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for ROS1: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros1 ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros1 ``` The **`zenoh-bridge-ros1`** binary will be generated in the `target/release` sub-directory. . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:master` for the master branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4979 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-ros1_0.10.0-rc_armhf.deb Size: 1540224 MD5sum: 88e105f4a6fb3a8f8a37eb422cebb386 SHA1: dd6e27d7359ab30d77f38683bd8a5f4d308ff795 SHA256: a2262100e52e76ae9ed4bd58a7d81a5acbc9eb7998ba6dd0736b32f027ce6980 SHA512: 0a25e6393aafffd606e0974a268687cc7e6624f6cb5200a91588836e14b8ad1b062d775aebc3caa996effe6ed8d2310a44fc363ac8560ca25ef4f6409574df7b Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 ``` . > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros1` (plugin library) and `zenoh-bridge-ros1` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for ROS1: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros1 ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros1 ``` The **`zenoh-bridge-ros1`** binary will be generated in the `target/release` sub-directory. . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:master` for the master branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3588 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-storage-manager_0.10.0-rc_amd64.deb Size: 1048064 MD5sum: e9294a73e4e91d032bb8f633b6a6cd06 SHA1: 9a5c807987ad65b20fd1d060d74fb1fb505c65b2 SHA256: 4cb5a6bb2bbce882a556ca88ce67f5c01acae69a026440c8c68b05199aae42e3 SHA512: 26f13266bc5633e87e77dc46585e5805e367ec8736f6d90a70c322ee9ce75742cdd736c93a45f16bc3d1b100f5a3bffc4e9a27d3aeb1327e3ea0928437435d01 Homepage: http://zenoh.io Description: The zenoh storages plugin. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3120 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-storage-manager_0.10.0-rc_arm64.deb Size: 921052 MD5sum: 083699f49b8d2e036ba3605422827327 SHA1: a2899c9a8d011700ea001e90d5a69525a7053190 SHA256: 9de28ac5736e2d037070137d8bbac18674297f79c2ffa736f27466c2aecc886c SHA512: d820c60963f183a98934852b79b9dd8b97c691bee7a4c09cffc65f459045000fbe31cbae7fcf6ef1da5b37b58c2ec55c95f3f248fd1a064c94b710d56d1bb748 Homepage: http://zenoh.io Description: The zenoh storages plugin. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3151 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-storage-manager_0.10.0-rc_armel.deb Size: 946948 MD5sum: ee3087e9ff19697fa5eb0b0ace594e43 SHA1: b4a94005b1e3c4007e319127ed80a569cc78a38c SHA256: 0050f75dc7576e79882d2333a2afd736a48ed7563db23939f9286d1e0df14b04 SHA512: ac8bb019c7b0df2f775240689120d5e901f46393ef35f9e0757fdcd18bfd90c25e92873d5566301f5a23b2a7390f9b230cbb7924ab2767001e7cfde2cc87fcea Homepage: http://zenoh.io Description: The zenoh storages plugin. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3067 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-storage-manager_0.10.0-rc_armhf.deb Size: 935220 MD5sum: d427f828f65b7db267a38a957cfc91df SHA1: 8fe7fb44ff74a38d44249acfdd4ff75dd40520c9 SHA256: 464234d82d643cbaf2aaabb6ec5fef935e47192eeb1e95538b65e79d06935993 SHA512: a8b5d36287c3ac6ddbe4f0fe304a420c1794cfecded74225ee6f94a005145d40060f7e958f4eb1cf0d38319c4b03389ddf2989954986766b000729ca87fd16a5 Homepage: http://zenoh.io Description: The zenoh storages plugin. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-webserver Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4711 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-webserver_0.10.0-rc_amd64.deb Size: 1328888 MD5sum: 21f6c8bc29baedaaf4e818fa94b1f32a SHA1: ddc9c0b073e77f750a857294a5e6e14ab80210c5 SHA256: dba48af9a81b2d4843e66106aaba402b021cc99d36f95829f2006aecde0dfed3 SHA512: 6a1b5c771270a24c94ce10777b0c698bcaacc82ee8bb5ccda3e2153d5a77c00f6465b10b2cdd95f4fe7cc0347b0e064a49513c6f2c8f16ff6122d39c0c2a7813 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/master/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4359 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-webserver_0.10.0-rc_arm64.deb Size: 1186532 MD5sum: 9fd788118d389d58ecfbb5d2cb6f2246 SHA1: f2b3799719c1d42e6759728ff89e8e224285dd89 SHA256: b64a0f4ddc70f400e7cd291583450e07a0e37a07b0c40d138c14cebd68687dff SHA512: d25747e6d428de03f20b441b87415d830ca54c3aeece89760ea238c012e08f7378d8c67990799ea559b929ed2ed7cd531acae268d18839e485b123d64e3ba14d Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/master/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3986 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-webserver_0.10.0-rc_armel.deb Size: 1128604 MD5sum: 82d3a58b899333d17476f7dcb21926ec SHA1: eb9107069cd7fe9bc6924b500cf8cbeb5e833dc8 SHA256: ef8db6a8a689344f28012c191d4de4608531d2484ea6b83ca3017153781c8941 SHA512: a6962d4f838527f6f8845db16c0b2b9e5fd1b0015a1299ca592debfab7c19c8ccdfb6b3d4cd21e90f9163448b23d4c855909cc2d8e136d30e83f9b55749a7bde Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/master/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3894 Depends: zenohd (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh-plugin-webserver_0.10.0-rc_armhf.deb Size: 1116572 MD5sum: 9e51092d8b1dfaaa32aa7195422573f7 SHA1: d569544aa05686078295b62421eecaeab61d3565 SHA256: e5072600e3b30e791c74e067b06b49dc3872df629f2f6c885d13659ed3ca6b89 SHA512: 0971dee236563f7ddbf37904e3ce07b7a38e141fd369792ff09fe2da9fc7abfaf5ed3d560b945beb92fb844af8c5f80b2c2a25905f3d1556850a9e1013eb4a72 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/master/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh Architecture: amd64 Version: 0.10.0-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.10.0-rc), zenoh-plugin-rest (=0.10.0-rc), zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh_0.10.0-rc_amd64.deb Size: 832 MD5sum: f4aa83d43081d5500a4a64521208e8a8 SHA1: a61b2121e780052282041c97aaf763a21138b45a SHA256: f4112e19f50b2c3167609a0ca46fcb09270c661803e105f7f967ea7f032bbd53 SHA512: 745354880734383662071a7c0d325aedbeaf808efe917611cf74c9384ab93fb916c43da7a917009fb89e9cf9040425c0a1fa35be19065f075dd591d1140034cb Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: arm64 Version: 0.10.0-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.10.0-rc), zenoh-plugin-rest (=0.10.0-rc), zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh_0.10.0-rc_arm64.deb Size: 832 MD5sum: 604c0a916efddf15b2366bb484d9818f SHA1: 702784fe4f42e507b3e75fb16fb76b99afc6c122 SHA256: 7522612dfcb97181b6aec4887094d03dbe4cc92320052fa87c2f0088ae3d0d65 SHA512: 39d94a0e5869937692ef8d2bade01a6105a10d4e5690a67d379f04b0034e8abcf8082cea1dadc94fe60673f1e544b91e16bc1b931676f700c51d38a91dd3713f Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armel Version: 0.10.0-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.10.0-rc), zenoh-plugin-rest (=0.10.0-rc), zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh_0.10.0-rc_armel.deb Size: 836 MD5sum: ef333f50c4f18f9f30d48b5f25c53454 SHA1: 612b49f14196548082f1dffdd44e05a9f42aced1 SHA256: 19b5d85682fd579f8cbd6157558a9992d387dbe48c92cb1f7315ad619aa6b201 SHA512: d943ba474a78a8315a3753e4fb479af5ce8b6a6614dca8acf08c443db13e698143ee8d96d22aa34a4f920189821e3cebec3b0d2588bbb46fb62c073eb3ec2ba5 Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armhf Version: 0.10.0-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.10.0-rc), zenoh-plugin-rest (=0.10.0-rc), zenoh-plugin-storage-manager (=0.10.0-rc) Filename: ./0.10.0-rc/zenoh_0.10.0-rc_armhf.deb Size: 832 MD5sum: 816104060637c7ccc706f86046b52203 SHA1: 0c2d91d2e2021d8cbd1efcbe74d3e21976717562 SHA256: 3502fedb97354d4f0ac4365caca02533c6335ea0f1244ece44326ae262ab9126 SHA512: d17aec7c3d243d3e261ab9b198c2f02484a7bdcadf587a7bec3b86585990dad4296bfa3899e5fe3ec99f3add443043bfae3c07bd336f7ff8b047ffec81e143b2 Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: amd64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9020 Depends: libc6 (>= 2.29) Filename: ./0.10.0-rc/zenohd_0.10.0-rc_amd64.deb Size: 2797776 MD5sum: 394edf59e44d5b8583c7f0607d207abb SHA1: 079de5ce34b0d88fcdb236bfa702438431fe67bd SHA256: db43ef41a8394a5436026b7ad91d2b3df5cc7a38c6aa09ea43a96853cff4f457 SHA512: d0c7d13d07116953dea63d0d1daadbe0c8637836188c86e4066969431c91b69a6f0d44a799f929d64cbbb50e340bc00bbdacc70976d885bb7f6e5de6efe1395a Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: arm64 Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7740 Depends: libc6:arm64 (>= 2.31) Filename: ./0.10.0-rc/zenohd_0.10.0-rc_arm64.deb Size: 2521456 MD5sum: dc048b78d60be1b1d2e84c871a05a7cb SHA1: 95d63a761682c8e2a1cacf0e308069e92e517b4f SHA256: 965510b1bb863483e6bdd0e99866ca62327bb7b1d5de691aa19d35a8b70eb348 SHA512: 0f82377df56a5d95dd7987d702f01dde7015a45962ced6b7ba9190b2245c2c9d468e9fa60a909bbafa50a978021171945e7d8c01c273c5c185aba8948f52168f Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: armel Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7918 Depends: libc6:armel (>= 2.31) Filename: ./0.10.0-rc/zenohd_0.10.0-rc_armel.deb Size: 2497704 MD5sum: 9f9acf6204feca899208e22b7de23d16 SHA1: ce3e3557aa718e39c55326865800ec3c046caec8 SHA256: b5b9405e2b09858e1af02ad616c92d09a788c53069f9c3c36c6a3d5ffd262b80 SHA512: 1a649b2509a6c5b51018480019c3f9c8d7c86378f3014719b8cfd63f5d316c61f07dd559a765489574be7d8be4d65ec3357d42d1870be98ed03fcf011c4255ec Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: armhf Version: 0.10.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7710 Depends: libc6:armhf (>= 2.31) Filename: ./0.10.0-rc/zenohd_0.10.0-rc_armhf.deb Size: 2490436 MD5sum: b8c90fe09c5642eff87f8a06cc720617 SHA1: 869ed21f8d45f8c4f064890977ffb196364cd502 SHA256: 08490e271c1fc3b7ab3100ba5e7845883ac4f7001bd069e2b8f0344cf1019f6e SHA512: c17b11261b5042b465060f12b5be52e082ccc8b94e6fbfb32835fad05b73fb2394d6d323907f851371297099650a0ed8ba7de0471b0dd0ccfa3e9aadafc2163e Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohpico-dev Architecture: amd64 Version: 0.10.20230928dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 405 Depends: zenohpico (=0.10.20230928dev) Filename: ./0.10.0-rc/zenohpico-dev_0.10.20230928dev_amd64.deb Size: 54832 MD5sum: 86019b6226dbb964ac2a717039344516 SHA1: 7f57e2b304109f6335e0ddfb69058c26329c48ca SHA256: 2bf5be03be9f2cbfaada8530b7fbdd9bbc1ceafc6327ba75144f6255fda9fe09 SHA512: bf8f39b10b23cf4e96030086335b7be535894b2365d7efe56490230cb38f81f8e117be678c07c4cc1aad97876665ed71b31207729fb8464af8af34e76cc576cc Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: zenohpico-dev Architecture: arm Version: 0.10.20230928dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 405 Depends: zenohpico (=0.10.20230928dev) Filename: ./0.10.0-rc/zenohpico-dev_0.10.20230928dev_arm.deb Size: 54824 MD5sum: 88b7eac9c3da7768c8eec6bd781f19fa SHA1: a857893c32972983f121ba1811f46f318cb23506 SHA256: e7611ff1c607f1b07f2a2a801d3d266506e82bb2b27377ca718a90af7779ccee SHA512: cd79bbebdac5231c48a1d1ec64dc8bfc7d202619a7ea17a862ff183e429b77183e48809bdb00e74bd83331d8807760f84cd5c91dbcda51d7dce2cd6abd28b1a7 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: zenohpico-dev Architecture: arm64 Version: 0.10.20230928dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 405 Depends: zenohpico (=0.10.20230928dev) Filename: ./0.10.0-rc/zenohpico-dev_0.10.20230928dev_arm64.deb Size: 54828 MD5sum: dff847a94bf9533fa4b436927dc3af9c SHA1: 2065dc6b07f75606797bc15075cb71eb42473d6b SHA256: a659a050c03c8d619f64d5ed7fe04dee0d5aa5c44adc354e1ac4aba10f44e82c SHA512: b2f5b1beae4d42c904ad6a0e46482e0ece5926a25bde23c26a2860b639c0943ba23f8c7d34a708f5295692c245e146238c70f0258b8509d114079f4b498be2bb Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: zenohpico-dev Architecture: armhf Version: 0.10.20230928dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 405 Depends: zenohpico (=0.10.20230928dev) Filename: ./0.10.0-rc/zenohpico-dev_0.10.20230928dev_armhf.deb Size: 54834 MD5sum: c6b93e724be624202c6597d5c1615a1a SHA1: 2dc6e067950be0dd8f43de88d0f24e4efd46fa8a SHA256: e089dd9850757821f2aa427495ec52aa941960cb21c501f187e71cc02ac9f807 SHA512: fc0dde61b1c4f18fddeb4290c5c6e03ea4cc0fc48173e60c7a58ccade37aebc46b567aa96c682d6bb87726c6ef0e93489f135e369782727002b0c0f4fc06605a Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: zenohpico-dev Architecture: i386 Version: 0.10.20230928dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 405 Depends: zenohpico (=0.10.20230928dev) Filename: ./0.10.0-rc/zenohpico-dev_0.10.20230928dev_i386.deb Size: 54824 MD5sum: 7a9035cf1cf09b36f8e8b3253f60d026 SHA1: dc2762b3d7c118d2347db2d5dbc0e667bb5860b1 SHA256: 168e98eab97a1e162a553349b1d795632e203e0b730260df1a37442e314d856e SHA512: 4193385bbac9c5a728e6b6d4a331deba27b4f1fa8c038b7bdb60be70d16ae8f4f9e8c6385d96afc9f6e7f1dd966a20662bae2592e73f6a668e3d505509ed4e60 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: zenohpico-dev Architecture: mips Version: 0.10.20230928dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 405 Depends: zenohpico (=0.10.20230928dev) Filename: ./0.10.0-rc/zenohpico-dev_0.10.20230928dev_mips.deb Size: 54830 MD5sum: a39be35f0b52c0a7e4828d4231a66743 SHA1: 0241524d3c98f6441d85d179dd70a3a743b472cf SHA256: 92b8f27ebd7e1f24dd00bea1c7217ef1732dc4dce707ec1889e5379c5b4a9ece SHA512: b4b93d2405e98251bdc2ab5fc4baae0e7b6014738e8a8284aa5d1bcf747abf1068c466212abb979104f2f6db6c33a3f762ff441747d830b38c7a47331225e404 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: zenohpico Architecture: amd64 Version: 0.10.20230928dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 473 Depends: libc6 (>=2.12) Filename: ./0.10.0-rc/zenohpico_0.10.20230928dev_amd64.deb Size: 120646 MD5sum: fea14660c90c127c64bdd0c39d8b557e SHA1: 6b87010ad1dc67d2b8068483845809924581135c SHA256: 3c2ccba71e8e3a31579eceb4edd08b8af25ae607a80c7400f95bebd85c46df40 SHA512: 150c6d0030b1261ed0120424e341dde5a1f6b60a9b214cac3f01b5f15cd478d21dbfdecc293910cef5fef8a4371d54fddb0bf8ec61f79763ec82f1224e4c3f04 Description: The C client library for Eclipse zenoh targeting pico devices Package: zenohpico Architecture: arm Version: 0.10.20230928dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 302 Depends: libc6 (>=2.12) Filename: ./0.10.0-rc/zenohpico_0.10.20230928dev_arm.deb Size: 89398 MD5sum: 3c1b6996a224d299de5888dc4ef4d69a SHA1: 38b974c4bfe78b68c129a680f0da25d65b0d617a SHA256: cc49152890ad068fdd42a0472cc90e5aaae754f3107fadb4787b8a9f341946ce SHA512: 171c58b9859f47dc6e3eec3e815bae3ca46959224a2f057539a605a43cf6cd0b4111c98ee0ce535bbdfb01cf6fd3f71ff5c61cc9c61640da0d57b8cebbba29fb Description: The C client library for Eclipse zenoh targeting pico devices Package: zenohpico Architecture: arm64 Version: 0.10.20230928dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 471 Depends: libc6 (>=2.12) Filename: ./0.10.0-rc/zenohpico_0.10.20230928dev_arm64.deb Size: 117184 MD5sum: 5fc071fe6da2b84b4ecf2859d0b498e7 SHA1: a5db4566e4f053add0aa68e5bbaa7a09b3e30fd7 SHA256: f7830182a4508ade58e41f8e00c2cac2e89c44dcdeafd6e42bb00a4b51495a5f SHA512: 60b7c3bd661b2afd7a9a3600899e1e2ff0271137fd7db32bb962565ae977561d126587a8734a2ab9373c4beb2c30a41e0296e988f8e659ef11fbdb9ac9b21f24 Description: The C client library for Eclipse zenoh targeting pico devices Package: zenohpico Architecture: armhf Version: 0.10.20230928dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 298 Depends: libc6 (>=2.12) Filename: ./0.10.0-rc/zenohpico_0.10.20230928dev_armhf.deb Size: 88434 MD5sum: c7bc7f69ef827c21cdc0b10f54f3e9f0 SHA1: 429ed473d7bb61b9677e78e061994b63185e1122 SHA256: 1111e53a786f70d3d8138bcfcdfcf1370e413202961f3cafe7a6b9105910d88a SHA512: c685c6fa3713c50803a13c683953c44cb8ec9b3a07d166daee0a7021c608f69b4fd131c48731f173a26437125576f65b6958970b2e5011d6eb7dc5cf282ed0fa Description: The C client library for Eclipse zenoh targeting pico devices Package: zenohpico Architecture: i386 Version: 0.10.20230928dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 446 Depends: libc6 (>=2.12) Filename: ./0.10.0-rc/zenohpico_0.10.20230928dev_i386.deb Size: 135346 MD5sum: c3a66ddb041bcacbfc6f055ee97a3cab SHA1: 4dc30006b102e82693a8e6d30356b41165a0cfb9 SHA256: 05809088c35795f9f21023aa3a542e68893adbf944f29797fc5ea958f5d6c0e5 SHA512: 73dc45b6bca772fd0b1280b7e237794019bfc761b06063585e7553be019a46c628423441330203a2ba94dc90272b4ec3d23218e24ca6525915a8fd771e75564a Description: The C client library for Eclipse zenoh targeting pico devices Package: zenohpico Architecture: mips Version: 0.10.20230928dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 399 Depends: libc6 (>=2.12) Filename: ./0.10.0-rc/zenohpico_0.10.20230928dev_mips.deb Size: 110982 MD5sum: 6fcc4c631fbf8880abe61162168d05b1 SHA1: 289120781557f89b13661132c21f3e485f1349bb SHA256: 56aa65600e61155630655f82682f80905462de8980cdafe015d387125a785081 SHA512: 537a72f502da0b3d6b9295dd0cebbfc6e2a3eda6bd8a3f6a4931720cb5c2bbdab4719aed050f0cfb0c722fe04e90d50100a8841c804038b37e20ce5d5a900031 Description: The C client library for Eclipse zenoh targeting pico devices Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 0.10.1~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11396 Depends: libc6 (>= 2.34) Filename: ./0.10.1-rc.2/zenoh-bridge-ros2dds_0.10.1-rc.2-1_amd64.deb Size: 3575892 MD5sum: d4318ee73ed6745aeab0602196310020 SHA1: 69970b73f2047a4d2cc1f2d60439af969f1c92e4 SHA256: 8990621256205462829dac763e26097e84927aa08b1fcb6c59ba7ff43cee0a24 SHA512: d772f11f439faa5034f3b08fc13a94c495c2373dacc544b4fa42e48f36c45ec5b65da7919711a27ecac9c4f756802d35616e46118fd2a17e774ab30f493063de Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 0.10.1~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9972 Depends: libc6:arm64 (>= 2.35) Filename: ./0.10.1-rc.2/zenoh-bridge-ros2dds_0.10.1-rc.2-1_arm64.deb Size: 3252016 MD5sum: 6f78e793ec5501eb296502b7ed4e8da2 SHA1: 754ef2cb6f12ba7a1cd49262f20af8e9a00f37e4 SHA256: 44e781967c433af51d234f37a328e6950616a69e3eb0f7b567a2dc8c8ffbabd2 SHA512: 12822728411d3c39bdd7f98a4aa9363db8344c407d62522e47da4d5cdd4d5d2df27b29baaa2123d8456fa766fc5f2ae257737abfccdd302178b4156f0bf6b4b5 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: armel Version: 0.10.1~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10085 Depends: libc6:armel (>= 2.35) Filename: ./0.10.1-rc.2/zenoh-bridge-ros2dds_0.10.1-rc.2-1_armel.deb Size: 3194208 MD5sum: cc1b96ebc9e0a21fbf3540848690abc4 SHA1: 4358cea296fa05b782196d1f115cbed5144586bf SHA256: 3dcfe7a7ac1c8ea0da49de12890b13b9255a130b052df62c16001a464e8eddb1 SHA512: 17916ffc10dea5a1d90edd1b93c7c54b4928c89451e219f7f24ea1d2da5753a775d63a9a0a326d1fe707be11d8b657cf30f475d396fac370d1826b71b72fea0d Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: armhf Version: 0.10.1~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9609 Depends: libc6:armhf (>= 2.35) Filename: ./0.10.1-rc.2/zenoh-bridge-ros2dds_0.10.1-rc.2-1_armhf.deb Size: 3200096 MD5sum: 62cc9374171872cc6c4dee796e451d52 SHA1: 474bd675b74870e2f6619a0cd0c955cd37ace5e9 SHA256: 06ac7ad2e3ddd7b25fe4608e07ff89787fd69e3d16c090b540662b872c677d22 SHA512: 57fa7131fd81dee6851b1eb28656fe550cf9b56049fe34af3eb73ad58c8edf895e33a85b0fabefe8ad7e9ae167ec5551811ba9e6fd13f635daa0be935844e8f9 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 0.10.1~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4876 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc.2/zenoh-plugin-ros2dds_0.10.1-rc.2-1_amd64.deb Size: 1462788 MD5sum: 08bafb9ec3d95a090094afaf46d98f1c SHA1: 91dc6eca872e53ec85e827db0d693119fb23b968 SHA256: 48802e976957d1f2fa138ca2983d3d9153e5ef8ad9c9112c8b953bc58ad75bde SHA512: a11c6eab495672a2ab4ddbc1db685146bd978b1113697d55463532e5ca30ab80c6f3e8f9f617a844a116343f3f49689ab6116e5521cc1f1932813eed6ae08cfd Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . No version has been released yet. Therefore only nightly built packages are available. . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS, unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros2dds` (plugin library) and `zenoh-bridge-ros2dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros2dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros2dds ``` The **`zenoh-bridge-ros2dds`** binary will be generated in the `target/release` sub-directory. . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds -l tcp/0.0.0.0:7447` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 0.10.1~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4327 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc.2/zenoh-plugin-ros2dds_0.10.1-rc.2-1_arm64.deb Size: 1298344 MD5sum: f4926712052a3c67afd84c261822ef04 SHA1: cfaa759e35903ef641e4dc409cb0bd8b7e3fff1f SHA256: 2a54de8e3ed563b35e526212627435adaa54f0ff2c1b04dbe94e58132459e986 SHA512: 8339f7f58376e25476e97c410fb549069e061c36ee6fe7c9da1b549c0ba11a44eaac09ef3176aaa11d29220a640720383b12a3507668a1989c5de2d94b51e066 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . No version has been released yet. Therefore only nightly built packages are available. . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS, unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros2dds` (plugin library) and `zenoh-bridge-ros2dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros2dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros2dds ``` The **`zenoh-bridge-ros2dds`** binary will be generated in the `target/release` sub-directory. . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds -l tcp/0.0.0.0:7447` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: armel Version: 0.10.1~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4226 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc.2/zenoh-plugin-ros2dds_0.10.1-rc.2-1_armel.deb Size: 1284360 MD5sum: 8fcdc748a9a3dca96c917b1d2633a8d8 SHA1: bdc1008143286d50db43f7fef76e1b1022718fa5 SHA256: 476b75669bd84977240c8ffd9c9c46e52cbe101f26622ddf6c50cd8bf8f723c7 SHA512: 398997adc2406dbdd6a81dd7b28e0ccba55774959223091b53186b31c40edcdbddd11006014507c8ecd622f12ce68473c0ddd1abe2df09c699b01df562435cf6 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . No version has been released yet. Therefore only nightly built packages are available. . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS, unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros2dds` (plugin library) and `zenoh-bridge-ros2dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros2dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros2dds ``` The **`zenoh-bridge-ros2dds`** binary will be generated in the `target/release` sub-directory. . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds -l tcp/0.0.0.0:7447` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: armhf Version: 0.10.1~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3898 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc.2/zenoh-plugin-ros2dds_0.10.1-rc.2-1_armhf.deb Size: 1291712 MD5sum: 85a94b1d968f5e967d69ba92da706947 SHA1: 791b25607600e551061a1d5966e79660a0057298 SHA256: 0fc2cad2809d82387605f14765907ede5c60fdcab6b8428c98fe288c7b56912f SHA512: 1b4d4c70f4bb1c4678cd5e8dcdce38de999de0523648d08eb7bbacfce357dda6ad3369bafda64a79439efe588ec15430313b007978c54bda5890ebf70aa12109 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . No version has been released yet. Therefore only nightly built packages are available. . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS, unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros2dds` (plugin library) and `zenoh-bridge-ros2dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros2dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros2dds ``` The **`zenoh-bridge-ros2dds`** binary will be generated in the `target/release` sub-directory. . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds -l tcp/0.0.0.0:7447` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: libzenohc-dev Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 159 Depends: libzenohc (=0.10.1-rc-1) Filename: ./0.10.1-rc/libzenohc-dev_0.10.1-rc-1_amd64.deb Size: 30624 MD5sum: 1a7382234d90d296dd33278c1284a536 SHA1: 52f0fe33d5c7198600439f9280503feb5c67ec79 SHA256: 8e393eb737c048c1c81480f6ac533e711fb2f6390e798012415bc69b7783619f SHA512: b247311da5ec406550becd8c0fdb591adea59141dcd5ef9d1b93e8919220e61ed610c3a29e97eabe07fcd7e18ca975384e69e20080e59126b41c52295afb996a Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in zenoh sources: https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/Cargo.toml . ``` cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 159 Depends: libzenohc (=0.10.1-rc-1) Filename: ./0.10.1-rc/libzenohc-dev_0.10.1-rc-1_arm64.deb Size: 30592 MD5sum: 3d38cb09adf17a01f80a79a4dc184abc SHA1: 3f425783a5822f3f19991c6d45ef8cda95feca3d SHA256: 68ceeac9fcdfe593d3110415a33716799985c70cd014884915e4e99ae6ce346f SHA512: 4c037566d8062881d5232fe49d7e676770265501b431979f767e8c14a4bdd35fbbc5dd6ca85230c8291b15961a0088b43cf3a2dea8a014b28dbe97c7d6cf4055 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in zenoh sources: https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/Cargo.toml . ``` cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 159 Depends: libzenohc (=0.10.1-rc-1) Filename: ./0.10.1-rc/libzenohc-dev_0.10.1-rc-1_armel.deb Size: 30608 MD5sum: bf5472df54470bc5f92bd49b95989e6f SHA1: 9d76405eb92ccb0b606cc72ff92ac7650b78ba4c SHA256: 21b84912414b1ed39133fa88172376ab87de8edfda51d19dcb47114b0f9af1e1 SHA512: 1ee0e83392c3a4f719b914917995a38aeb8c2e9bc62d9d75c577b1dd13f76a146cf5e2c218c5ae4d67cfdb9c12d620636d6b5917288db0e4493b5600ca4b2cc7 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in zenoh sources: https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/Cargo.toml . ``` cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 159 Depends: libzenohc (=0.10.1-rc-1) Filename: ./0.10.1-rc/libzenohc-dev_0.10.1-rc-1_armhf.deb Size: 30612 MD5sum: 5aa8c46eef5d9383e51d6ff23bbf3a62 SHA1: c30edddd520d0f4fe9b99d797f4f74f78782cf38 SHA256: 5b65253295baebc931800e6d29b43891ca75aeee777cda335cb4ad1c1ff775ee SHA512: c128268f7576a68268ba9604469aebc15d4d6d01460e80bce11b81c1d66ba63d600805c18ba963f6f7ee783b93b2e0fa0885501cbb0aba18d99f5e22c7474c95 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in zenoh sources: https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/Cargo.toml . ``` cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13521 Depends: libc6 (>= 2.29) Filename: ./0.10.1-rc/libzenohc_0.10.1-rc-1_amd64.deb Size: 3631132 MD5sum: 6bd8ca508f3f7967c04ae9ddddae44a8 SHA1: 8adeb01032699179b6f6b2cd02ffb05ed8238b4d SHA256: a128eea07aeb2b785f90b8767433fb0af22d0b79896f557b041519a9572bad56 SHA512: 007e7111a78c5c051780dbd50dd9f9ffa8bf218a4a47314581c7e3a68df17f0c5c1bd1863e86061693bd12ee26fa659262a233a1e7fc6847ab3a4a70eac16568 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in zenoh sources: https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/Cargo.toml . ``` cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12437 Depends: libc6:arm64 (>= 2.31) Filename: ./0.10.1-rc/libzenohc_0.10.1-rc-1_arm64.deb Size: 3331776 MD5sum: bbfc8a5a81db33760be5174f5e66ee97 SHA1: e0604cdbf29e983e25d39d227a9915e8f7e44491 SHA256: 7fd438231f92408a5f9dad94799e15cf06ec3d307ecfd1aa0c9ebd4bdc1ba8aa SHA512: 968293787ff82e9ef85ded4fe5f8fb334384f890e058ce72d5249dbb519dc427d1e1c0d4d2cde6173a7635670be203988da61ed2f7980e0c5ea68e4eb4c930c5 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in zenoh sources: https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/Cargo.toml . ``` cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12999 Depends: libc6:armel (>= 2.31) Filename: ./0.10.1-rc/libzenohc_0.10.1-rc-1_armel.deb Size: 3453068 MD5sum: 0becb6b46c36ff0b07cb761ccb29e22f SHA1: 5e489dbac28e8ad9133b66d3982d059bd1b953fe SHA256: cd8ad49a209ce376be55d53ceba06b68974647e37de6654b2785a985aca6e2d8 SHA512: e94ac3d497052809824bdfbadcc8562f3baa8a10c3cb7fd728ba3cce324487c2555a956c2bbb6637ac0681d67bd649e945feabe0bd72d84cdfae35c308e980a4 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in zenoh sources: https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/Cargo.toml . ``` cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12728 Depends: libc6:armhf (>= 2.31) Filename: ./0.10.1-rc/libzenohc_0.10.1-rc-1_armhf.deb Size: 3437140 MD5sum: 3291b495aa5a2a53563fd2b71a08d88b SHA1: bbe5ee9b0584bb5689a602269ba21ec4966497e1 SHA256: a05c7c360be2480591bd838969c9ac7c8829431c3226921adec6cfef105928de SHA512: 90e95406f5d604dcdd431c8facf6d9d4bae00b9a47f2409fd0a1c634ac33641bad328194e3a048daa76067cef0c697089a868d28732c326aa7f87d8089ecbc14 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash $ rustup update ``` . 3. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash $ mkdir -p build && cd build $ cmake ../zenoh-c $ cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash $ cmake ../zenoh-c -GNinja $ cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja]: https://cmake.org/cmake/help/latest/generator/Ninja.html [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 3. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash $ cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local $ cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash $ cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE $ cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 4. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash $ cmake ../zenoh-c $ cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . Second way is to directly build `examples` as a root project: . ```bash $ cmake ../zenoh-c/examples $ cmake --build . ``` . In this case the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash $ cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.8.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/z_sub ``` . ```bash $ ./target/release/examples/z_pub ``` . ### Queryable and Query Example ```bash $ ./target/release/examples/z_queryable ``` . ```bash $ ./target/release/examples/z_get ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/z_sub_thr ``` . ```bash $ ./target/release/examples/z_pub_thr ``` . ## API conventions Many of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we named them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: * We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. * We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation * The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL=nightly|beta|stable`: refers to a specific rust toolchain release [`rust-channels`] https://rust-lang.github.io/rustup/concepts/channels.html - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [`cargo flags`] https://doc.rust-lang.org/cargo/commands/cargo-build.html - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [`targets`] https://doc.rust-lang.org/nightly/rustc/platform-support.html. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Lets put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you use `nightly` ) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in 'zenoh-c' directory. Notice that build in this sample is performed outside of source directory ```bash $ export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" $ mkdir -p build && cd build $ cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL=nightly -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage $ cmake --build . --target install ``` Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in zenoh sources: https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/Cargo.toml . ``` cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: zenoh-backend-filesystem Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9939 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-filesystem_0.10.1-rc-1_amd64.deb Size: 3051732 MD5sum: 67d52789c750ab9a07224a8c54dbf0c8 SHA1: 9a9c9bf19215d3abcc61934db684f832bd714a41 SHA256: c8e20dd52a7506d4afafb0a59db0fe062184735aa7fccd0edfc913595e17c09f SHA512: c1bfb7e7861aa1420f0876089a28dc8e391ff092eb7d81dcc57cc7ebfd59fe4b5ba305f38ce75795b53f9e7b8e023414f23b620e02366a561f230a9c8531d42a Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8751 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-filesystem_0.10.1-rc-1_arm64.deb Size: 2650968 MD5sum: bc3dd25b20b0b6e995540a6913dd02fe SHA1: e97e25237b49e6401a101fb38617cdd9a5bc3fca SHA256: 04fb40f9f6c3d0e5d37913a734c392623c4d7904dd0af9d47b86ad8a9edabadd SHA512: 4aed022a07ee5c14dd6c884740230eab6afa5452c91ab16c8300601c1106c02ef4533d422b1df6e8781171799ce74b19cfd6766006f5bd88bc75a269b2c72b1c Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8326 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-filesystem_0.10.1-rc-1_armel.deb Size: 2594456 MD5sum: 59117a192a734c34aa6a7af4bf141c04 SHA1: 8bb46e8379c9120ea90f1ccd549a23b9d4ad9a08 SHA256: 6723c571bccd37e5b2f8551a3b9d34bc4b67082f347acad097040cc79dbf6482 SHA512: 39e9775cfa34fa7de1d5e69e32b605e37fd444f49af6e733aa8d817fc99d6dfbd3d8a4a166e9d530dd680e1817bdb61ce6fead8dd90b2d1705cf40136f288b31 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6554 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-filesystem_0.10.1-rc-1_armhf.deb Size: 2693716 MD5sum: 864fc8e731fb21f54da6bd477c0b83f5 SHA1: f871ec40d08f27b660602827fa1e4ffe1e9e8704 SHA256: 3fa48849fd8e42774fed7914929ae52cfd6e3df5151edd0667b38da09f932301 SHA512: 9c8c54b6499d1c574c048d9f89528ab0515c52c792c6181ce11d57bb03f408ca8e1aa0eb09d7a2a3da53d3a878549d39836742a8099c6c131a765e22e815bf96 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-influxdb-v1 Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5392 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-influxdb-v1_0.10.1-rc-1_amd64.deb Size: 1690148 MD5sum: 7d7788e57fa21dbee7f9b1e10fc5b334 SHA1: dcf8f28f2eef79485c0265fbe900d740413671e0 SHA256: 5ae362f22cf55072ff7c20c567b0e3e3726eaa9a6db747838ca83e269a555c51 SHA512: 727e6cc34464d74ae6f1135c4a8c70a5d2a4a39f36c6c8450935bd6764942d4ba370851a742c54cf53ba4801b58efa4f80e3657ea6f61f11bd6beb23b963801c Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4860 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-influxdb-v1_0.10.1-rc-1_arm64.deb Size: 1509020 MD5sum: 4f00697a0995c8068a8c85340a72a0d9 SHA1: 4c92d5b409be1755e22f9217e8175e2c003af104 SHA256: d23edb8351d328880541b4b6dc65ad8acd70a286f141f880e78da33884f7b773 SHA512: fa1b16385f865508f5122ae0b06be09d9352d9e26e5bd1ca982d6af99289e65c3d2a98e4ac543f4980af7178bb40983492c8297d162fd19e7bd56b4bb35d41b2 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4327 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-influxdb-v1_0.10.1-rc-1_armel.deb Size: 1313528 MD5sum: 40a354dc87311d058d292d4d175e25ab SHA1: 3d52a541e2d1112cdb5fd8bca503f3eb192b366a SHA256: 385cffcfd6cbe17d40dbf21b855a275cf774500b2cf35c38ddbd0c249d8ed7f7 SHA512: 239b823a108964d5101ec1ccdb0eedc6b3d88763cc989ebec69e7022a41c481ff0746917dd49f249f4ff3f03c83b29741f50c1a6ebbce7395b5fb3813cae2eda Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4223 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-influxdb-v1_0.10.1-rc-1_armhf.deb Size: 1304620 MD5sum: eea1c4989984936b061f5b8fb6b1a5a6 SHA1: 68af25845c9bb35d85e5a7be86007031f0e2f974 SHA256: e80017c8ce6f41f3fa23bf466866ea4826b8eb7e5892266261dd9f19d1e6d810 SHA512: 3e08f848238f3b82d2b5c5209d168def9f71038c79a2444162ca2836543991913f1a1a7aa4b8414923bb2e99bdcf698fc0f261c1edcf27190bb43933d8525ab2 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7822 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-influxdb-v2_0.10.1-rc-1_amd64.deb Size: 2361412 MD5sum: 61316c6c78298755dbc59ee2fe44c164 SHA1: 9164957c39843ef294b6a7b1e538b017c23a5e14 SHA256: 498d273da604305fc68e464265e51ed4384bc96caa7a9e77bd572e73de3a6cf9 SHA512: 9af3c8b25f7a65919ab755490b950556b6315b269c615af905e1be0780c3c59e14e32f2aa5e5e7e190b51fe360c9ba89bc83a33bf74bd6989eab10dd46c0b60b Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7174 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-influxdb-v2_0.10.1-rc-1_arm64.deb Size: 2146204 MD5sum: 7f360e151e45c5d0b3c090ee88c58871 SHA1: 68171786d20aeaf14b2df769f1eadd1d60f0ed0c SHA256: e6b58b6f191178443fee17e6acf6b7d69c2c22e8809e8b4506444f8f499ef9a7 SHA512: 8f33c26086faa3fb0cd944f153ef823e3a46011541e5ee6318b9df0c7ad6fa0c177b4097d33a12cc40374254d9dfc0f23ce7815d3387bbeefd9d23e45ef9e1f2 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6352 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-influxdb-v2_0.10.1-rc-1_armel.deb Size: 1916516 MD5sum: c97457c3c614f9e47752b0176f1f373f SHA1: 3ad72781e47f0eb13654f1d8b7b6ea89a7589783 SHA256: b10d9b6337d7f573df199f3341cc70fd1648a18ab0d193cb8b6e0761962571d3 SHA512: 7a05f382b236f81d8bd9702b933ebdf95a63615c44ab8749b69bd58e9e5b8563db776e1cfde0d118f63a87f56bfb7331f3a0500f885628f7377608e5a17918de Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6224 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-influxdb-v2_0.10.1-rc-1_armhf.deb Size: 1915312 MD5sum: 068f868c1a49a1f9628f9aacaa27ddda SHA1: 5bc5bd721096e07ed4276663fa722ed32f0e6010 SHA256: 8ddd6622129863da16e3cd854dfa7a4c46a71e7b453338cb61e31cff70a4a5d4 SHA512: 67f25520e95053a6b8b6f5fde8ea8d5ba3effb9df64e4a5ef84f271a4cf16da86e6de7630787401d068d2785cced048a4fb142d33d74a6aef50f66acf3382f42 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-rocksdb Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9845 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-rocksdb_0.10.1-rc-1_amd64.deb Size: 3033436 MD5sum: b0beab0541d2b12d31fa996fb57ed52d SHA1: a7844740e4d25815f5d3421aa8f2eb17e1852159 SHA256: 819cb0ccbc7fee0b0c2abd1ef0b9dc4c3ba1a31dc3cc49ce73d156f2dd2f8007 SHA512: cfe6a77248f884bdd9e0cd5cc7e81fefd03d509e139ef275ef0e952c8bc70336a92241da33220fdbf587ecdceb727a1952a06921c8483b7bf040824b2a23c45d Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8641 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-rocksdb_0.10.1-rc-1_arm64.deb Size: 2629296 MD5sum: 706120034d31b959bf9a52b52e1899b4 SHA1: 6ce4b845ba684a528f6bbcc6d18261d2d25a4e6a SHA256: ca813742b5256101a8cd8ce9164c45f5947bd3a6f86e6bf883481e9f3a8de534 SHA512: 2454377855cad3ba0ec38ce93faa56048f6705c2d4aad8ee6c31eff26bea53d518a76f12ef715ef045004ad45081f6fe172aab9f2d6c986960ee6c82f500d47e Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8288 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-rocksdb_0.10.1-rc-1_armel.deb Size: 2575972 MD5sum: 34af0d2e21ffe501d787036eb10a7d3a SHA1: cd1b5240df7b82d262a95feccbe94a2dcc9ac611 SHA256: edfa37473f479a72d431f0b2d270e4370a3fdbbc67b5a932add6b228de6f462f SHA512: cd4cb69e8d5cfd6e0e1b466ca6e158efa85fbb7a96eb092806dcd5e908a5ce9a16884ce152417c64fa22d0ceb6ed5e867d4c4bd898a212c914b386e4d0a476dc Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6476 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-rocksdb_0.10.1-rc-1_armhf.deb Size: 2682808 MD5sum: f3adc2a9be3449c6a28e1e8ec5540503 SHA1: 84be270d8b707ea9a74f9e74037f53b4a0ed986e SHA256: 905b50ce0df20dd0183a3bb36cb87a007d9d18922e7706db430aa8ab880ed0dd SHA512: e497890a181fa11a569b48eebf3e42039cd04ebf641af0ffe37fe5eb14f174266facb9f059e64ad7d2bc5170c07cf08529dd1d9d625ef376d92740a3351ae8f3 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-s3 Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12430 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-s3_0.10.1-rc-1_amd64.deb Size: 3122248 MD5sum: 53e3c96717d543eec1407fbfd96361fc SHA1: a4b27ba5524ae747e92813660b64fe3097c25b5f SHA256: a7cf6977c15e7551dd538fb8e3b14461e76c6797fea6d666611489416b1d8b33 SHA512: f6bd19c79cec68dbc7ad5831381d546707937cc1305e8d4d900321ceb0a913c6d44103de63cf826f224084215960e1816178bf6d0cd3c698c26f2d012373fa77 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11247 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-s3_0.10.1-rc-1_arm64.deb Size: 2857924 MD5sum: 16ae10907c2ed48da58ffc751916178b SHA1: e1e3277a6d6267a6ccd0c3d18a5d7c86a9c7d091 SHA256: 9e69051775f1b07fe2afcc32705b3ce158a3ea1e42c6baf624041d47bb6e90bd SHA512: 8cc095683530bc1c6a3fe84ac0c18ab4bd0e23b59a1420a05644814d81f6bf0391ddab118a35a640509b6ffafafe5b13caf38bb5fc69662bbcde9d52376e7d0a Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9995 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-s3_0.10.1-rc-1_armel.deb Size: 2550124 MD5sum: 482b2edbd4ba43757230c17d9310627d SHA1: 596cdbeb54076b3fd85fa0dd4a1b4999fcdd6dfd SHA256: 592528743342f1fa0c2b95adaf21f4dc4d681c3971a2b4e4c5f5da45df03b290 SHA512: 3a2c15a162cad427926be9b4fd9b56d83efa8d02326d36d2a3c2d86aa4f2a072a24a41b13d223f7c75222702d1acfbc3d1041f7f0717c9c87d536e7ea17b4b6f Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9767 Depends: zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-backend-s3_0.10.1-rc-1_armhf.deb Size: 2591760 MD5sum: e68e2203b8cefd331e19d6ebf854df54 SHA1: 62a8f6b398918d000cc42566c93b8990029096ee SHA256: efacd2b2054d62a917d95a4f4446f5dfbeb21a5b2602130006606d533cedc8fe SHA512: 6ed7e23d22331321714bc90448262b2bfa36cdf40754651d8b08dcff4134497b20624280c1e47743e25c38955a7ccf46be0de4b6a1b0054f7277e9cb61b2d974 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-bridge-dds Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10979 Depends: libc6 (>= 2.29) Filename: ./0.10.1-rc/zenoh-bridge-dds_0.10.1-rc-1_amd64.deb Size: 3479060 MD5sum: 55d4634a3562e3cbb4ef037f20f3b9f3 SHA1: 9c3ecaa018551170f620abd40ff1677dd294dd43 SHA256: 0d94348a0826d8444b1554c908c107aa3fe1445484a1f487b0444c2f7440c19e SHA512: dec98079c93b89042c946d2516d555ea3d23a319d864f24edb28c5779bf64bc414efbf8cb99a3cb5d4f4f7e8ab49093e3ebe4604e5b7437231e4bbdd2bf96cd6 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9606 Depends: libc6:arm64 (>= 2.31) Filename: ./0.10.1-rc/zenoh-bridge-dds_0.10.1-rc-1_arm64.deb Size: 3160804 MD5sum: 266a7381ca442ca7edf0b5106705d3a9 SHA1: 7e17d8be2f5c98241ac4f1b881fa708b9384f58e SHA256: a164dd9853689c00e620446e5eae2f357768241b287554fe7f703ebc59fbed3f SHA512: bd30cf06f7c9d9a2068c0ccee0aaab0ca4ef1777a88ec46587a8de7f34a6b3e34b34f199c28ce0dde41a7211480d94cd31c824966d45cfcc1304b9cb437f2888 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9712 Depends: libc6:armel (>= 2.31) Filename: ./0.10.1-rc/zenoh-bridge-dds_0.10.1-rc-1_armel.deb Size: 3103544 MD5sum: 0c71b28a49023b6683dc273e15ba0733 SHA1: ea66d33ca4549f6c3878faaa04b767bfa9cd4786 SHA256: 0540954cb2127b56a37b3db12f8b9c42bd4aae7992100af9b259dd587706892c SHA512: ca7a5f030b0d09a478af8731c556edd608ac821cebd449c144e9f58cd3aa4605fe6ba2356f0e95506e8dfcef70298ee2da7c01d25876e4107e3ef27ce5f2262b Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9244 Depends: libc6:armhf (>= 2.31) Filename: ./0.10.1-rc/zenoh-bridge-dds_0.10.1-rc-1_armhf.deb Size: 3102832 MD5sum: afe5215ae2e5c733df716798bd0c8d88 SHA1: 8d75fc6bb3a4897053ad109918f3def705a7d2f8 SHA256: d727599da405dd4646a21bb05b08c09b6ecf85c5179445f0f832871af43c2b55 SHA512: f89bd6116fde877ee97edff73b6aef907ebdd2158aedff252b2250a83f4db1fa60cf4cad791c78cf2fe6984e14eb1e16311dc88814dbd8c6201b8eec5686d469 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-mqtt Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10124 Depends: libc6 (>= 2.29) Filename: ./0.10.1-rc/zenoh-bridge-mqtt_0.10.1-rc-1_amd64.deb Size: 3168812 MD5sum: 7de8244a42cbaf75fef5dbe21739c6b3 SHA1: 5fd0d5d48fc0714cd01285dd2da566ac404d82e0 SHA256: 8e90435d377cc2635dc96d680283ae74edfd53e7ff5003ecfb1417468b5add43 SHA512: 2b897517a5d6216bce6d48ecac98bfa9144ee0315f03701fba0aa74ceb2ba7121a360e75756fd7ff69ec11124a9903df4f512d297ba4be031a848bfa78166757 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8768 Depends: libc6:arm64 (>= 2.31) Filename: ./0.10.1-rc/zenoh-bridge-mqtt_0.10.1-rc-1_arm64.deb Size: 2872212 MD5sum: 5ca60187967558532222351c631edad2 SHA1: d4dc30d3d39c0a7ec5dfb55c70cf08426af105f6 SHA256: 9ef9f6b6daa74c2dca753a5fc077ad9cf37663aa7a499270e5ad9ca5067dca4b SHA512: a5bf2733a7ebbba4d6bf10eb23503c3face2f1a72d2f946157d8d434b37098da6bdffc5ef5b05968c32b6b05bde299dd2205e85dfb3934d3b7cffd1076acc505 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8994 Depends: libc6:armel (>= 2.31) Filename: ./0.10.1-rc/zenoh-bridge-mqtt_0.10.1-rc-1_armel.deb Size: 2840164 MD5sum: a8a240bda9f3a4aa80c97102c3a5cd8f SHA1: c5a48d7419b140da8cad8275799bbbc1f4778fcb SHA256: 428c98b3929c251f21fd23d0f701501c0bec2b3dd2ddd354be7ebed5449c0ac4 SHA512: c89f79507117f08c754a1b8f14e85769beb45acd757867bdcb18fa4287554187264b36b9c0af873d974adf890b94023454a8abb2534e03118c7af7b3d3103f7c Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8758 Depends: libc6:armhf (>= 2.31) Filename: ./0.10.1-rc/zenoh-bridge-mqtt_0.10.1-rc-1_armhf.deb Size: 2824544 MD5sum: 497e35b70cde29aacdda216b2730d041 SHA1: 492cae888d53a90038c4d2970640a62d7c027a11 SHA256: 61784c0592b62849989fdc8f61577ef23219b9b09138f20d9742f0488a5b82a3 SHA512: 7eacd345e5aea0a9b7a9dd85f8e8158b0504fbe082a8431dbb1c5d5004fd393289fda865a54fa71962007538e0ce18383f96d03ecf591a5990ddc9c180aeaf18 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-ros1 Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11328 Depends: libc6 (>= 2.29) Filename: ./0.10.1-rc/zenoh-bridge-ros1_0.10.1-rc-1_amd64.deb Size: 3407832 MD5sum: 6db0974fa78777744ea4f032ad636d8b SHA1: 9187ce79105d31b45cccac495b18dab60e68af99 SHA256: 847de9c8a15bee2ce438d98ccbddaf96b6691ee78fca473d9538f6a2df0ca9ff SHA512: 6e1cb64047371b6fb30b05d32261d59a5a08456bf39afab189a7be47f04955d2df7a07886a3119229f9250c5da5cd22bc5cae1811b9043563b99725fa03276e3 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9804 Depends: libc6:arm64 (>= 2.31) Filename: ./0.10.1-rc/zenoh-bridge-ros1_0.10.1-rc-1_arm64.deb Size: 3070740 MD5sum: c924e1faf7fa5ddd2e252b968c58835e SHA1: 204f810bee73d7bcc0731a3dcfec9128e58e4fd2 SHA256: ab160312baffa5d9ae4dd872c6c54487828e77072a65e612bb10ea1212f9fba3 SHA512: 79d715796fd612bad519bffeb0a826a8261dfb5d25356671c2cda21ebda0465c24191d2567b78f98d716b86135ffc9ffe8636a3c678a3d9c53b12ec0e9a2b50b Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9990 Depends: libc6:armel (>= 2.31) Filename: ./0.10.1-rc/zenoh-bridge-ros1_0.10.1-rc-1_armel.deb Size: 3049116 MD5sum: 6be3717b2faeb63610f1546352d33038 SHA1: bf0525d71b1b82c40d335ecf0abf98675010991d SHA256: b9a2cd7302b37b70f43061acfbab79712cd67df9dad5e6aaff26f1b87c744868 SHA512: 1fd78375c1ed8979edc45ce30e888ac0fb8090859cfc01ea901b643316917e930d372f2a49e06324d8aa6899369c44da180acb005726b23d51f6e8bdd046ab4e Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9726 Depends: libc6:armhf (>= 2.31) Filename: ./0.10.1-rc/zenoh-bridge-ros1_0.10.1-rc-1_armhf.deb Size: 3038872 MD5sum: cb051feefd13c54dbea33105f989f2c5 SHA1: b6779064064374fc67d38b4f87050151e3ea6251 SHA256: b92ead7a77ae008816e8fb8979db6f8a49b3990dab2eb132918001dd6da18811 SHA512: eb775c290627752d5e93cde94440da139d8d8caa2847e994750ee0b701bd838161c231c40a38d4088409055b966b4570bfafb6e41aa6a0065d7b55c244000016 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11332 Depends: libc6 (>= 2.34) Filename: ./0.10.1-rc/zenoh-bridge-ros2dds_0.10.1-rc-1_amd64.deb Size: 3564560 MD5sum: 160b6116d7626f2155f0403591bb89b6 SHA1: b2647f1279ceb3277075070964e0214fc3781c69 SHA256: ee4ab42e53d30a3457da5b934f416b6e36f231d65ed21c01663003702c1a9302 SHA512: c867bce35aeabb6ec3f72eb23ab39a5914883692c5a4837c43fed8e3136a49e2ff921de1da8d45473e29379cfde57b0d7455aac12cac6efedf966145f1fcee10 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9920 Depends: libc6:arm64 (>= 2.35) Filename: ./0.10.1-rc/zenoh-bridge-ros2dds_0.10.1-rc-1_arm64.deb Size: 3238684 MD5sum: 0e764f7322e40a198f3d99ac4b37eeac SHA1: 1d0fb33c787085bbfe211e1111e5ab8b03616fba SHA256: a5a6db2ecc1521e9facc05b3230c51e8afca294a3ae40f5c7c955b1e35b9b4b1 SHA512: dc55f6efc24a4a9b75ab074d6015bd05c423bff78304c2a7bc9f4d5199afb926b338a02bda74569e61c4bdbe68f29c4d705ff06d6092cbe8ab2485cf02b4ff8a Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10057 Depends: libc6:armel (>= 2.35) Filename: ./0.10.1-rc/zenoh-bridge-ros2dds_0.10.1-rc-1_armel.deb Size: 3189828 MD5sum: d37989032fb4ffb2735b912f3afdcb66 SHA1: 24ab9aef02cafce3e0138093ab1dc68de346dc94 SHA256: 498a77ba97316ebe4d2a8d747ee1fd0255d968205677581e2fe7145e9d5bcbb2 SHA512: 626c2a82ee03fcb1334736c7ee8c334014acd383f5feae784f5de2c0513f61ce9b59e412ce9946374ab3066f1a5eae93064fa132970435a38bf5ee809b281b7a Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9577 Depends: libc6:armhf (>= 2.35) Filename: ./0.10.1-rc/zenoh-bridge-ros2dds_0.10.1-rc-1_armhf.deb Size: 3196264 MD5sum: 6e749ff0ec12b36f7d229f0e5dc68562 SHA1: 19fe420c7d7a91f7dec06ebcd43ff76a18da10a7 SHA256: 21c2c7b7dd20655818d38bde0191bfe9c5c1c099dbea3c5e3cded14bc62b1359 SHA512: df7b959443088c6b2a5d74a958c82e82a623057c4e4af040e803b8069ddfb1fd036bbe945e2fe9776f27fc211d7c45f3d7cbd0ff53da36c49acfa9e8c9761629 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-cpp Architecture: x86_64 Version: 0.10.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 181 Filename: ./0.10.1-rc/zenoh-cpp-0.10.1.1.deb Size: 26230 MD5sum: 26713607d604df96eb0e4bc528a5f79d SHA1: 604bab3c80acebc3c14b96061a068009a4537679 SHA256: 20161380a7b698b42052223f4b5a49dd55f2085bbc8a7306c60ca7170cc53eb0 SHA512: d1f8f6c2faced1ff51f228dd40a4676c293d84079b2a8d5d2a5a36aebbc0288a375d971c016f7ce2cc04e6faa99d36d3bcf0d8faa655309fa80fbe112f2809a9 Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: zenoh-plugin-dds Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4520 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-dds_0.10.1-rc-1_amd64.deb Size: 1386304 MD5sum: 1187fada95c1a617f86424f7775b909f SHA1: 2acebcf111ca90f7fc7c168b362abd99ca60b0c7 SHA256: bdb0897f89efdaf4c80ea1a11dc5d8166f1d84b25509580448a574e9df5e8433 SHA512: e086c4bb5b544f35b9d76be8e76afc6c919f9551d2f8c035db48686c843a04510b33fe192e058fc4f9044442fa564dbbc42f1ffd85e67a524fb3dfebddc163fb Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-dds` (plugin library) and `zenoh-bridge-dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds ``` The **`zenoh-bridge-dds`** binary will be generated in the `target/release` sub-directory. . . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:master` for the master branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . The `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@/service//dds` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//dds/version` : the bridge version - `@/service//dds/config` : the bridge configuration - `@/service//dds/participant//reader//` : a discovered DDS reader on `` - `@/service//dds/participant//writer//` : a discovered DDS reader on `` - `@/service//dds/route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@/service//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@/service/**/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@/service/**/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@/service/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4028 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-dds_0.10.1-rc-1_arm64.deb Size: 1232316 MD5sum: b053a879282b3d41c869039015cb1636 SHA1: b02dfd8a39bb395be68d6248f79997c047975979 SHA256: 10144042ef4f870681ddaf024b2bc021ea7abe83aead774c4e3f80d100bd6c22 SHA512: 86e1ee6001c6914d603a18a2bc1fd5e9e14be96516568941e302a02caba435ec5dc3ce61eea6161e1f5f504624c3a632f9d3d9c73b5d1eec1befe6dbe7fbfc64 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-dds` (plugin library) and `zenoh-bridge-dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds ``` The **`zenoh-bridge-dds`** binary will be generated in the `target/release` sub-directory. . . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:master` for the master branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . The `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@/service//dds` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//dds/version` : the bridge version - `@/service//dds/config` : the bridge configuration - `@/service//dds/participant//reader//` : a discovered DDS reader on `` - `@/service//dds/participant//writer//` : a discovered DDS reader on `` - `@/service//dds/route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@/service//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@/service/**/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@/service/**/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@/service/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3915 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-dds_0.10.1-rc-1_armel.deb Size: 1209628 MD5sum: 91bcf1fb2461d39a438303cdde0dbba4 SHA1: 592d638f9d596af46bfb797051ef5b0982113485 SHA256: d28193e6b4421a15b7f1c01dd709988e1df2099ddcfa86bc7d71a9d525c508b7 SHA512: 1f7eacab620039685e06efe5d4709d7ec87879b3d9a83beb5de18bc44f21cc621097a47c3d3d048b189bf27a0e2e195ae1fcff3873f0e11cc56c049908ea9eeb Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-dds` (plugin library) and `zenoh-bridge-dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds ``` The **`zenoh-bridge-dds`** binary will be generated in the `target/release` sub-directory. . . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:master` for the master branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . The `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@/service//dds` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//dds/version` : the bridge version - `@/service//dds/config` : the bridge configuration - `@/service//dds/participant//reader//` : a discovered DDS reader on `` - `@/service//dds/participant//writer//` : a discovered DDS reader on `` - `@/service//dds/route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@/service//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@/service/**/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@/service/**/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@/service/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3595 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-dds_0.10.1-rc-1_armhf.deb Size: 1215636 MD5sum: 334d9509737ecaccb804bbc08d837000 SHA1: 72b7aa1361468201b30183cd96719e502dccd64b SHA256: 1b17d78e667fd7639f46d52cafa7d693f830ba9ca3a781235c519ea87f85f135 SHA512: ccb5f86dddcb48d94906d3eeb1816b17c54de4e4b6fc24294d7b305ac8d33ff3061c34bea6419982e7edd1e502dbe16d1e9bc55e4bb1169fc7ceea9e37796ee5 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-dds` (plugin library) and `zenoh-bridge-dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds ``` The **`zenoh-bridge-dds`** binary will be generated in the `target/release` sub-directory. . . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:master` for the master branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . The `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@/service//dds` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//dds/version` : the bridge version - `@/service//dds/config` : the bridge configuration - `@/service//dds/participant//reader//` : a discovered DDS reader on `` - `@/service//dds/participant//writer//` : a discovered DDS reader on `` - `@/service//dds/route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@/service//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@/service/**/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@/service/**/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@/service/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-mqtt Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3627 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-mqtt_0.10.1-rc-1_amd64.deb Size: 1051844 MD5sum: 19b8a49b2259698d662e11fa2f7c56d1 SHA1: eef25a38f6a47df9580a0f900ad53f18eae1eff5 SHA256: d369af22491a3bcc5a4d2c5b3cfc5fa522ce4fc73366e4b5944d7917cf8ffb2b SHA512: 1e93134ede401f19b2bc1b929a5e1085104f947ae0fbc1f5795c78dac60cdd5f75b2bc93f58e0e8cda7c3e46f4c60c95af8bad170e4b2f21ae9110488f6ff77d Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:master` for the master branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt ``` . > :warning: **WARNING** :warning: : On Windows and Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-mqtt` (plugin library) and `zenoh-bridge-mqtt` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#19](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/issues/19#issuecomment-1754742678) for explanations. . You can then choose between building the zenoh bridge for MQTT: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-mqtt ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-mqtt ``` The **`zenoh-bridge-mqtt`** binary will be generated in the `target/release` sub-directory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3183 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-mqtt_0.10.1-rc-1_arm64.deb Size: 924624 MD5sum: ab60431d2a938f827998a0e0c910a4c0 SHA1: e9cb86b323d61048ac152cb46228f7ca231fe0e2 SHA256: 3e07b8a95aefa19273b2a365445c534183187f3e0215bafcd710cbc0440cf7d8 SHA512: 00b17d88683a37b81a87ea13c96369c62f4665c2b4b495eaf70eda1b6897b553d29475bdf19cf052833c1ef03663dad3893cd015dbbed569b9df926b51333087 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:master` for the master branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt ``` . > :warning: **WARNING** :warning: : On Windows and Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-mqtt` (plugin library) and `zenoh-bridge-mqtt` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#19](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/issues/19#issuecomment-1754742678) for explanations. . You can then choose between building the zenoh bridge for MQTT: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-mqtt ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-mqtt ``` The **`zenoh-bridge-mqtt`** binary will be generated in the `target/release` sub-directory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3154 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-mqtt_0.10.1-rc-1_armel.deb Size: 925460 MD5sum: 8b8cda22afbacf3ff67848cf7665d86c SHA1: fc4806803605c9c866989e88a4ca101d93d244aa SHA256: ac330ef2f36419b38cae67b2063412385adbf0737d7ad047150e5bd47c7b6f54 SHA512: ae8c2948acb4fb81749121526533a04f923e1abc8d10057e97b420bdc489b536544515f4077ec823c414e292afb88f890b01430abb71a60a2cbfa937769cfbdf Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:master` for the master branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt ``` . > :warning: **WARNING** :warning: : On Windows and Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-mqtt` (plugin library) and `zenoh-bridge-mqtt` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#19](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/issues/19#issuecomment-1754742678) for explanations. . You can then choose between building the zenoh bridge for MQTT: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-mqtt ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-mqtt ``` The **`zenoh-bridge-mqtt`** binary will be generated in the `target/release` sub-directory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3074 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-mqtt_0.10.1-rc-1_armhf.deb Size: 914560 MD5sum: 62d1b21c490beda395b305b127092f1c SHA1: d43300b6ecc47f11db05546b64d2693f67bd18c2 SHA256: 7d70c73040714eace1072269a8e4a35eca41b0773d5f7d2a9f61dad9e76b7fe7 SHA512: 1ab8ab852d2af957765cd15ab0cd28f2b3dc3ad7570049dda92739ec9823e782e1bdaef347d0b5d88e32ebd59955e037a8e25f34c042cae388107722f782ce47 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:master` for the master branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt ``` . > :warning: **WARNING** :warning: : On Windows and Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-mqtt` (plugin library) and `zenoh-bridge-mqtt` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#19](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/issues/19#issuecomment-1754742678) for explanations. . You can then choose between building the zenoh bridge for MQTT: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-mqtt ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-mqtt ``` The **`zenoh-bridge-mqtt`** binary will be generated in the `target/release` sub-directory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-rest Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3636 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-rest_0.10.1-rc-1_amd64.deb Size: 1063252 MD5sum: 0806f9cbde20e0ebc8410da89e1b9700 SHA1: 6edfbd7f92c9f85b6325cb4a31fdfa24175aa196 SHA256: b01089b85b2ca49209061160565c683ccc44f41db3ae6ba2ee1aab6578e20123 SHA512: c4f8e771e119fe9e66d7348f0bae36ed369e385141acc359c5008ec478cdcf99f928873272fb5771dcf1bba29f86a91426edb7ff759ea8f0722f19aff9d20325 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3200 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-rest_0.10.1-rc-1_arm64.deb Size: 938952 MD5sum: 9ec2905fdea3975e41338926351c6d8f SHA1: 192ca6ae01c0964c118afb21b3ebc5684547f632 SHA256: 45086bba5255900a03a9fbf6facfd4afe7dea37b0885d088deda40dfd0473ed3 SHA512: f2955e3833ef8e46e177ecbf57cb8477501ae125cde2cc0a12c0376f93e34a6f6b46b6ad8fe582bb1dee2f6068a7b22da91cf76bb588f65ec31b6881a7dec3ce Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3159 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-rest_0.10.1-rc-1_armel.deb Size: 944504 MD5sum: 0b2d6452a2e8d35aa0a3a42205d0caa4 SHA1: ae9d1ad508eca56731f74ef9b10d7df17ecbc4f0 SHA256: 73ec80a50dc819fb834b7e5b2177d16a30c0d38453bde4c10f9bc3a44890c430 SHA512: dfc5bc726a131462f1c22b651231b8707c1a6ede8b28cb997e1b84a6b9cd5ce4b7d6eef0f643486305f723f5c3bef69f360eb963d064a93ca81dc410b5f969d9 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3083 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-rest_0.10.1-rc-1_armhf.deb Size: 933788 MD5sum: 3efdd05c23c6a28dbab022caf318895f SHA1: 51dbe76b921de51bb23de1105a11db9790ced7c5 SHA256: f899a7e8555cd960a317290b19ae612aec8a91700449c47d42298efcd6d7d8f8 SHA512: 29cd317f2f5684625976205686e8585c1f05a375523aaefbb7fc0fbecd4d666ce8bc31776f533f8a705927925e981e195b50fc4c8da7d2ab2f1ae07c14e81ae1 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-ros1 Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5628 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-ros1_0.10.1-rc-1_amd64.deb Size: 1681324 MD5sum: 69c97b1f2a9871286369bbea31e3f8f2 SHA1: fed38aeb5a77fd7965e9cc96f07c193f7f013e96 SHA256: 584584aee006f459c403886c9f4903ad4ca42c846858e4d2afa16f40eeb35d6c SHA512: 560a87c3bdc8a3e180b98beea925e39917c4b3d8ee6608556965d7e9bf8df33fbda9aa02bf2c3eb328031e9e5ee40d0cc83838259c2f76bc809e789be7858769 Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 ``` . > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros1` (plugin library) and `zenoh-bridge-ros1` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for ROS1: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros1 ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros1 ``` The **`zenoh-bridge-ros1`** binary will be generated in the `target/release` sub-directory. . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:master` for the master branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5032 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-ros1_0.10.1-rc-1_arm64.deb Size: 1527824 MD5sum: 13c7b0e73224b1ce05582c85c7a1db6d SHA1: eda359f2499327775505aad9b0ca18337bd61ccd SHA256: 632755967f84e9b5279a61ec75a9cf508cab83ac426a30480885a2c99a2347d7 SHA512: bef0bf39a3d200f72c29590c11389fa0156b40ec3bf812b3cb8a024212ab237a33bf5418a5e7d065eb9b858c2df95f8f9bf646cb8625a558031b4baa0a966faa Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 ``` . > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros1` (plugin library) and `zenoh-bridge-ros1` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for ROS1: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros1 ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros1 ``` The **`zenoh-bridge-ros1`** binary will be generated in the `target/release` sub-directory. . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:master` for the master branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5131 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-ros1_0.10.1-rc-1_armel.deb Size: 1563332 MD5sum: 246a1412b0ce4262d9bbe7081d7393bc SHA1: bad3eb060864cc85301e18259d941bfb690e3bd2 SHA256: 6a6d0ab7a57a70e022b59d10ca8a410d864cccc5afeff0dfb4e08e188b294936 SHA512: 352ba79dde704bf403c96a16ae073ffc12aad75ffb56c5d09525cf8cc5513f283e20c7cd4d251c3a52907d9469e566380a7cc4813cb93fb05d93a1e6d403927d Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 ``` . > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros1` (plugin library) and `zenoh-bridge-ros1` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for ROS1: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros1 ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros1 ``` The **`zenoh-bridge-ros1`** binary will be generated in the `target/release` sub-directory. . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:master` for the master branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5007 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-ros1_0.10.1-rc-1_armhf.deb Size: 1546260 MD5sum: 7a9c03ed3501d3221cc7874e41458c83 SHA1: 8d1ce0e9b1fb45053778382506e01ffdfb20fabc SHA256: 0b26b5a60c9ad74db6d27a0ea80abbcfb16cc2575b8d74a2dc7597e53b0b638a SHA512: e3386ad5a618b5c63458edae174f78bfa21be550f477d803e1503ab2051b6e05ad9ea2344dc45e013811fa7d6d566eec058130577d3e565c912fb3be80157a4b Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 ``` . > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros1` (plugin library) and `zenoh-bridge-ros1` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for ROS1: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros1 ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros1 ``` The **`zenoh-bridge-ros1`** binary will be generated in the `target/release` sub-directory. . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:master` for the master branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4860 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-ros2dds_0.10.1-rc-1_amd64.deb Size: 1457784 MD5sum: eb47e3ff5773acf9d480bae9e3863391 SHA1: 7589ddc4d1382610223795fd51a2356d7826c274 SHA256: 33d061137ef08a079cfad8e840ad828e7bac50d08d3ba7d080a2d7e9087b3190 SHA512: 4374687f5270208439f6c5580178d9996929eaec29f41bc1fac4c87043ea6bcc4bc5e4770e32dd6cce6a685ddc9a729c0aba5b8fb0cff25311919c3982ac38b1 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . No version has been released yet. Therefore only nightly built packages are available. . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS, unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros2dds` (plugin library) and `zenoh-bridge-ros2dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros2dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros2dds ``` The **`zenoh-bridge-ros2dds`** binary will be generated in the `target/release` sub-directory. . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds -l tcp/0.0.0.0:7447` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4307 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-ros2dds_0.10.1-rc-1_arm64.deb Size: 1294256 MD5sum: a1322821376af993e81f2e895fe44397 SHA1: 22ec77fa8f3ab0d99b583206468014bca5709537 SHA256: 304ccaa055f57dec89f9736a69ae5fdf3e06f38c0208df89237169767239f2ae SHA512: a2bef193a3ee6dd2e807d6a5bb72efedf7e1f9bd31d81590889e70f7dc35609d911a8601b02fba06305562c3f10c3fe723dc92151364fbe87f554694555cba46 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . No version has been released yet. Therefore only nightly built packages are available. . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS, unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros2dds` (plugin library) and `zenoh-bridge-ros2dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros2dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros2dds ``` The **`zenoh-bridge-ros2dds`** binary will be generated in the `target/release` sub-directory. . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds -l tcp/0.0.0.0:7447` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4214 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-ros2dds_0.10.1-rc-1_armel.deb Size: 1281132 MD5sum: 20cd02876d01c0e3cdfc068b9acd7222 SHA1: 195d81f15e4cf29424e2494a1c76b913915b826f SHA256: 65e617ce8e57d8385dba7af82f22097c8fb1ad67e2b00cc14aa46a9b605c2a9a SHA512: 8abfff151cc0742ba538956a4203420f9afb375b438c3c872a1cf924bde6ea5691d3f6a377c0887be7e0a568d2e19f00b0dc4c3046a8b2576dc04f18562a47f3 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . No version has been released yet. Therefore only nightly built packages are available. . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS, unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros2dds` (plugin library) and `zenoh-bridge-ros2dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros2dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros2dds ``` The **`zenoh-bridge-ros2dds`** binary will be generated in the `target/release` sub-directory. . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds -l tcp/0.0.0.0:7447` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3890 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-ros2dds_0.10.1-rc-1_armhf.deb Size: 1287668 MD5sum: 98e58ba90a62a29286a40cd8111c068a SHA1: 636ebc52117fb318fca1566b7db9a5a3b2315d43 SHA256: ee301791fa029c52e68454208e0cb6f1f9122c0f172a07d9e4ee1c0a1ef1cf9c SHA512: e6489d0cb55a6ce99c53834b8254b7de3c5d9324ae162b8aa592e91671e409f62402741b409f2619e81851e15ec4a9c09ac423d558ac461ad07a0584b626a6f1 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . No version has been released yet. Therefore only nightly built packages are available. . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS, unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds ``` > :warning: **WARNING** :warning: : On Linux, don't use `cargo build` command without specifying a package with `-p`. Building both `zenoh-plugin-ros2dds` (plugin library) and `zenoh-bridge-ros2dds` (standalone executable) together will lead to a `multiple definition of `load_plugin'` error at link time. See [#117](https://github.com/eclipse-zenoh/zenoh-plugin-dds/issues/117#issuecomment-1439694331) for explanations. . You can then choose between building the zenoh bridge for DDS: - as a plugin library that can be dynamically loaded by the zenoh router (`zenohd`): ```bash $ cargo build --release -p zenoh-plugin-ros2dds ``` The plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) will be generated in the `target/release` subdirectory. . - or as a standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-ros2dds ``` The **`zenoh-bridge-ros2dds`** binary will be generated in the `target/release` sub-directory. . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds -l tcp/0.0.0.0:7447` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3600 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-storage-manager_0.10.1-rc-1_amd64.deb Size: 1047644 MD5sum: 0e30755e89ed47150e2f638b701c42f6 SHA1: 832194e69832885e6844706d8614945d1bd17dab SHA256: 3a2fdc7cf4b1d4ebf6204eede5d41b661a354f84d0277f5011f97d6dec01c502 SHA512: ed28ad2c431dbb2957e1dbf3d3f71ca02e2ba9cbf13c892105519a8404c8a8a599d0bf1b8f5e9ecc2c8d7eaba3d8e45aec6d729793938836c01e9260f215beb2 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3140 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-storage-manager_0.10.1-rc-1_arm64.deb Size: 920220 MD5sum: 386cff8467e6a01bfc3052b2d3746ae4 SHA1: 942d23f9b0c4beec9a50750b32b119dc82fd101a SHA256: 8471378260dcd793b9715f9067bb6bf7593e58fcd847f11325df7b33777326fa SHA512: 5e855ce016f1eee4ca55db124bb74e83297cbbaae39b543005612a50cb9ca94b6d37832e0d2ef0ed353bf60b59377c11969ea92cb3c0d40f3a48c0dc40b971f3 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3163 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-storage-manager_0.10.1-rc-1_armel.deb Size: 943860 MD5sum: a2b20ef2801bc15b7da8365c948c9f50 SHA1: dd60a9c52127362ff177c5863e7b479db3ec2218 SHA256: 04ec119e11bde064ea4edfea81c86938bd608a49b4240aed4ab23853765a7a70 SHA512: 3e3ffc971008e5c8edce33d5825156f075125a1a59cb4a99433f59b95f2bb7d6c694ba795113554e2fdcf386788ab3f2a8147931593730bc2709a3e64d74a58a Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3079 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-storage-manager_0.10.1-rc-1_armhf.deb Size: 932916 MD5sum: 11ac06323b1cac9099be463dc9b045b6 SHA1: 25c90c04f0291eea454f5be2e614ce189de46ec0 SHA256: 4de8c18208fe52804f2d797c8aeb19bc0976b042378682f8fbe523b5c3eaa465 SHA512: a2a7b94fa9d3ac23deb1dc7bd1f2e745cbed779f36f99d62039b8ffb46dd70deb2d7e36b7608b752f7bfbc0138cbf16604e50ea0f57f49005604bd9351f44055 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-webserver Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4767 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-webserver_0.10.1-rc-1_amd64.deb Size: 1341528 MD5sum: 17c47714edf12647d2cb8aed6761f308 SHA1: 558acfee7b85c8d5b1a852218b6a1beecde5c0f0 SHA256: db287a79392a8d392135c434121f910594f8c42f9dd057fff755fb1c3f03c0dc SHA512: b269d6e0a5d372efd27f858fe7a0dcac7967e7f9cecddf36adaeccef61eee13f36debdc6dfc9c8fabd05284febe3d9c73416eb0f4d51d90dc6d857ce66738a54 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/master/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4387 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-webserver_0.10.1-rc-1_arm64.deb Size: 1192860 MD5sum: c331b74aa63845cb91036f94d8bb3f6d SHA1: d50a702876da470f42b89c3f7b2ff6e7fa36c23d SHA256: 108d3cbe2e914292ba9f287b0abb8b8e7f93c705d873ec269f0feaae9a484e64 SHA512: 63c94579f3baa8016706f39ddfba8b604cf98d1ccefa9b8164d7e790c35f90ee025caea9daf21106a8bc8ca1a7b9d7d009f2d7b6792456692cc5a8ff82bdc809 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/master/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4058 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-webserver_0.10.1-rc-1_armel.deb Size: 1141392 MD5sum: 2b2d0a1e13345071a68e165b6770165c SHA1: 5fd3be7181cc5b5f91a85e55e24188d5d5537d2e SHA256: 7de02a0e45984767ca3b58a3bc182eb0ddd706e4ef1417acc998a107e6e735b6 SHA512: 2160912f5a2e0d9529c023e8afece73699ec7332a3b7291376114b07a5d5225843c14e48ce3bc2e9f1d97a31c48cf4356372dc9b43162d446587df04a8c9fb2b Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/master/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3962 Depends: zenohd (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh-plugin-webserver_0.10.1-rc-1_armhf.deb Size: 1128772 MD5sum: bc4c17e487e132319c0cd4b0057f18ff SHA1: a59ce5f2033d3f20261e6285348e12e1e7c0b591 SHA256: 489e3ccba5188fd2618f51504a59eaf0d9bcc5e898bc064578dc3f73fba625b9 SHA512: 7d9acd75f38b20c6c4de698113d2f3acbd5f491957c88c9bf1a22a9a68f85d4c42a3fbccdd412123329e8bdb850598842ddfd001aa119b663ca065d81bd05f14 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "master" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "master" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/master/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/master/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.10.1-rc-1), zenoh-plugin-rest (=0.10.1-rc-1), zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh_0.10.1-rc-1_amd64.deb Size: 836 MD5sum: 703b27f54e8f91041d3be132cc16feb7 SHA1: 9f2224d0278052cd32a0f54d774660b55cab1786 SHA256: cce7ece3dc9abe1eb516fe3b263452753f25343035f003626916aee801e50f99 SHA512: 74b4ff43b1f67bf0e96579abd163d446bbcf3f799731bbda634dbe248e713fd808a7032d9519e8f3999d56d049222b7d2d79b498c02129b1455a3c664182a927 Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.10.1-rc-1), zenoh-plugin-rest (=0.10.1-rc-1), zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh_0.10.1-rc-1_arm64.deb Size: 840 MD5sum: cf573f7ddcba408d57d5e261ac223c6a SHA1: 06fad9b46f6ea44c821ec427b3a52f3d8273bd0f SHA256: 088dc8f2cbf0e200283b9a69e4bba4670cc56687f7193854def7a4f4787a12b8 SHA512: 2810cda56d18cf8493d694a88ef812ad8b04afad75e9f344bf5ae66728d78e314c711a09c0a7d13855898b02f990b4e5efb54e38557c7d74f1c62fc5ab63e69a Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armel Version: 0.10.1-rc-1 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.10.1-rc-1), zenoh-plugin-rest (=0.10.1-rc-1), zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh_0.10.1-rc-1_armel.deb Size: 836 MD5sum: ba257ee156f206ddf1853c4d59b11f84 SHA1: 17f69d8a2001fc79ae56039c64ec971262778192 SHA256: f970040400f8a0a4ecef391f5a6322e5ead87c0341f5fb217a1a20750e140a27 SHA512: 0c207084b471b19f4958c773e9020b1de9b6226d383a034caa0edd936928254d3aea1872e408a7bd3777cc43e609f4f6fa4fa5d5983e124306844bb656169d2f Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.10.1-rc-1), zenoh-plugin-rest (=0.10.1-rc-1), zenoh-plugin-storage-manager (=0.10.1-rc-1) Filename: ./0.10.1-rc/zenoh_0.10.1-rc-1_armhf.deb Size: 836 MD5sum: 0f9849c5ca13fe6c05a57eb8701e45ad SHA1: 307b09ca575f252a83a5183e051141931f077b21 SHA256: 4f872977631a68cdd9a2c9768dedb85707f9e9bb862d7eb4e398b69dd22cbfc5 SHA512: 5fa30406337a53a8be6c889964a88cacad593bbc5a8d1a46e297206861f76319ab3989485b09f35e476fd8ef4d7bc4f46364a3356350ccac4bbd855164e17975 Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: amd64 Version: 0.10.1-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.10.1-rc), zenoh-plugin-rest (=0.10.1-rc), zenoh-plugin-storage-manager (=0.10.1-rc) Filename: ./0.10.1-rc/zenoh_0.10.1-rc_amd64.deb Size: 836 MD5sum: 4abf5ddefe290d1ddbe5fe7991f6a81b SHA1: 2ae93b1619fcebc7e559ab028b06f496f5a0dba2 SHA256: a966d82ca3ac97ad8fd80845e6825d7f097af66c2085abcf4ebb1f79e435761f SHA512: 2d26121bfebf9ad989e95229789ca2202c787045540cae194581fdfc1586f291d38e9bf3a7fc8f7a93c5db0257b95a7c66843dffbc65ae3fd262f8833cbaf031 Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: arm64 Version: 0.10.1-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.10.1-rc), zenoh-plugin-rest (=0.10.1-rc), zenoh-plugin-storage-manager (=0.10.1-rc) Filename: ./0.10.1-rc/zenoh_0.10.1-rc_arm64.deb Size: 836 MD5sum: f695b7f58c9651b177e31910e5362fb7 SHA1: fb9d9ad53072fad7f49813d20d8101188e33597b SHA256: e52a0dd6ef2c74dc5c968945ae7b859ee5912a1479a5ec271ec6ff02c26dae19 SHA512: 29ab5d43165c47b17cf9b37abc3dbbee365a41c5bec4ffdac710414238b900e5854f06079eeeb35828370b74961a0a02b0b10b79aee5b3443dae8ab2a9c3ca30 Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armel Version: 0.10.1-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.10.1-rc), zenoh-plugin-rest (=0.10.1-rc), zenoh-plugin-storage-manager (=0.10.1-rc) Filename: ./0.10.1-rc/zenoh_0.10.1-rc_armel.deb Size: 836 MD5sum: 3fea0f57d7cdd8ff6accf3da115f81d0 SHA1: f97b97fda49f74f5dca69a5bad7ca3df97824a28 SHA256: 35e41e7fe5fa2bb8d4e354f6ddef9783ab0763a6abb4ece8e1eaf68e56407b51 SHA512: 6b657473ddfaecf6cec5ae9137af080c0c580011e3c0953020f408772f1d0af59f295e35ef7f4894974f7f35bea90640d52d0403934c4ab5c7bb5d9c3764578e Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armhf Version: 0.10.1-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.10.1-rc), zenoh-plugin-rest (=0.10.1-rc), zenoh-plugin-storage-manager (=0.10.1-rc) Filename: ./0.10.1-rc/zenoh_0.10.1-rc_armhf.deb Size: 832 MD5sum: d0a15eac29421055a77024ac00e3a11c SHA1: 1b693789aed6cf65357d6329d3139f5dcce011da SHA256: ab3a75b513d6b0317e47599a6411ca5f5d33c3c3c7ae2b19bf388d606f8db299 SHA512: dd484061bd6bb826c0cbbf2bf833deb05241ba3f39a81edfae129fb9819b473afe431a07fdb46abbd1845480daec257744a1cf6b4cf8cd309055f66519ecdf50 Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: amd64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9096 Depends: libc6 (>= 2.29) Filename: ./0.10.1-rc/zenohd_0.10.1-rc-1_amd64.deb Size: 2810276 MD5sum: 4f868e2812827eb2cfb4985949bd0c84 SHA1: ece5e6cfebaf6c135b203b3762b2d1fb97aa5a26 SHA256: de108984b5097ae13dfb2e89cd70731257531737d810049b53946ccc993cd122 SHA512: a105ed98d49b6bd3391a143f40a9a59f8e0e78bed05c0f193237b4cab9c35de55422596b97b90d082686823e55fdc9579529216e63a35490379438b0534e9690 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: arm64 Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7792 Depends: libc6:arm64 (>= 2.31) Filename: ./0.10.1-rc/zenohd_0.10.1-rc-1_arm64.deb Size: 2533804 MD5sum: cc0c116c004464b9a529f0a1ba389c0d SHA1: e61a042566c1c286f70eca57eef09b620c9af87f SHA256: 8ed378791338ea17b9c4adcd4089f218929838dac31874322ab64482ebb834b0 SHA512: 666f5ca1a69840bf021419768a6b0c9f6bfcdcdcf9b7a7f89c865874e78b59cebb0495ac385c0a22a5b100fbf792ac34a78b282d8ecaa1b0ba7bd6b777a88620 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: armel Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7970 Depends: libc6:armel (>= 2.31) Filename: ./0.10.1-rc/zenohd_0.10.1-rc-1_armel.deb Size: 2509104 MD5sum: db1ea424262c56387c9572f46f0daf7c SHA1: cf1ffa2c27f7f0dab9d3007710c97d77fe0c8f76 SHA256: cb9c756ce20d898aaa5049d3baa8491adf62574a703621d7e43cfc75a99eb895 SHA512: 4736233e4b2da7fb4774bb655fb06b7773662bbd0ba8907ed75d3c738dde63e862dfa1326230263d8f697e531978ae61fc4a108dc512e696b666bc98bafb7380 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: armhf Version: 0.10.1-rc-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7762 Depends: libc6:armhf (>= 2.31) Filename: ./0.10.1-rc/zenohd_0.10.1-rc-1_armhf.deb Size: 2493408 MD5sum: 6a4948f59e0596cc7a58be8c2e51e3d6 SHA1: 3fd15eca584515b90272d2f69c008ffbadab5029 SHA256: 6ca2f835bf3c24102365ed748c5bbb735db1c8b3426b3d0aba76696ab2627b39 SHA512: 3a42869d1953b00c77ed383ae2727b1f41238f44efc937fdff4c91404e19d238ec5204a9f89cc6f5b1a1a2e79ce7a0c8123d47b9eca98bedd6263cba080b1352 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > :warning: **WARNING** :warning: : The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > :warning: **WARNING** :warning: : since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohpico-dev Architecture: amd64 Version: 0.10.20231221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 435 Depends: zenohpico (=0.10.20231221dev) Filename: ./0.10.1-rc/zenohpico-dev_0.10.20231221dev_amd64.deb Size: 58486 MD5sum: 0630bbef349bce6b39435956d1fe3a13 SHA1: 8ef1dc84abac4f149ba46fc8052b1521ad659671 SHA256: 586cbb1a312985047865d64aa67f439b4947e2e82071c7b4f2b13721026ef526 SHA512: 325ec2754a1fe2847f3b1592d0b4798b9e0da03f961d81779bb50882f731d161bf9e87f4625b391d647273b78531dee48b7e172bdd07a1a12f6088de73cef6a3 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: zenohpico-dev Architecture: arm Version: 0.10.20231221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 435 Depends: zenohpico (=0.10.20231221dev) Filename: ./0.10.1-rc/zenohpico-dev_0.10.20231221dev_arm.deb Size: 58474 MD5sum: 91877e3a673f11d7d26d0f0ba0dbb77b SHA1: b7334609d1fe28152259f9d6b858e08757426d13 SHA256: cf206cbef3e2bde41f3b9b4360498f3b7faf16d429462c4794b2e307cab24e92 SHA512: c7fef95bdd33259b7bdc22eea5222a36b0116e34659b8b2274031182e29b01d7386de10d3a0497c68b2661c09ad56e4c0b1ce73efbe2b1d524c3feabb1553c96 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: zenohpico-dev Architecture: arm64 Version: 0.10.20231221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 435 Depends: zenohpico (=0.10.20231221dev) Filename: ./0.10.1-rc/zenohpico-dev_0.10.20231221dev_arm64.deb Size: 58478 MD5sum: 1c4e3a34e8d9724a9d6eaf5faf3cc393 SHA1: 21b863fb47dbe8c97fc175f8fcac5a4f8aee9668 SHA256: 708ca9158c07ba72f461ed25d76e5754d4e5054353fab368c0942f590ed786b5 SHA512: 486c0eee975c66e2088101fec7862b7f09ae7e11e1a0826106d3dcddcd8d7a619811b3779d79dddbd0bcf36e545653455e41ee4823f640c69f69422d28b4ab51 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: zenohpico-dev Architecture: armhf Version: 0.10.20231221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 435 Depends: zenohpico (=0.10.20231221dev) Filename: ./0.10.1-rc/zenohpico-dev_0.10.20231221dev_armhf.deb Size: 58482 MD5sum: 206dc7284f84cb4f93d4b1105141f193 SHA1: 75cb6b522ae6b0eec2b6c3823a7a377399dd9acc SHA256: b5be65914516f849d51ad9b7f206f070f060b19368bf8abaccb49fcbb4e4a289 SHA512: 2f37e19ea66afa087cb7fd1a2ad39d6fe8844b98451b625b8c42fe5748096c8e56c206c7f1677d2522dfed7422333a7f07b8fe9d4584f30d84221a4148e72bef Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: zenohpico-dev Architecture: i386 Version: 0.10.20231221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 435 Depends: zenohpico (=0.10.20231221dev) Filename: ./0.10.1-rc/zenohpico-dev_0.10.20231221dev_i386.deb Size: 58486 MD5sum: f8601c3bc9dfb4970e819b1a189ba6ba SHA1: 1e83dd1e4fb5855d61a1948e205958d1253ecf82 SHA256: 528ac2bd808071e6e7e279ab1328ea8bae4b79a6d4653a11f21a5bb4dc3ed3d6 SHA512: fffd0f9f6af6fa5de4ec2b94c676bdf83f932f3d02ceb30046d9673db3307edead498dc1a3424e7ec3af757ad1a3da8272412bcfc5a2b77c85436aea5ac059dc Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: zenohpico-dev Architecture: mips Version: 0.10.20231221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 435 Depends: zenohpico (=0.10.20231221dev) Filename: ./0.10.1-rc/zenohpico-dev_0.10.20231221dev_mips.deb Size: 58484 MD5sum: 589b4ba3720bc5859eeaf37dbb63dd16 SHA1: 6670543e220d0ca9e9f96d00160e6647805621cb SHA256: a6e10005ac9c154f43a38019b477254a8b682b4fcf4f41f6f39b878b1afdc7ec SHA512: aa6633ee5ba0b40e56bf1aa2bee8cc97a726eccd00b07976d3c90df99bbeb815bae770dd08c1e24b619f504d0503cfec0786b55ca219e222800476d72d0a86aa Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: zenohpico Architecture: amd64 Version: 0.10.20231221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 489 Depends: libc6 (>=2.12) Filename: ./0.10.1-rc/zenohpico_0.10.20231221dev_amd64.deb Size: 123992 MD5sum: 0d6930e186d12da038478144ccbbba6c SHA1: 1b5721701d73127833265f900c03ef22bc5cab45 SHA256: 047f805b0a6210ef052b7206f0f02bbe9f9aa71eb49188276af421463fa7b460 SHA512: da61cce554a41bca476ca3a1893cbb0ac5ebe033f9b06dfa93530deb2f1281b9d877f78b795860a90809f03f899100a2893e30d643dc7578db1f50cf18d21f56 Description: The C client library for Eclipse zenoh targeting pico devices Package: zenohpico Architecture: arm Version: 0.10.20231221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 314 Depends: libc6 (>=2.12) Filename: ./0.10.1-rc/zenohpico_0.10.20231221dev_arm.deb Size: 91452 MD5sum: 372b766c617c2e2f6bcb70951d032533 SHA1: 1eef6fd8084100f07cf055b12f8288e56726b511 SHA256: ae56055e1c0afdb8cd4e99d1009d866b771aba82b5c9fe0e18f447040e325eed SHA512: 4db5e4092c4940a56bce34a829313c21d751c05594bf698561303d21ff78020ea5c30816ce04b9debecc96a279bb0376505ebcd1f795091fce5910c90304180d Description: The C client library for Eclipse zenoh targeting pico devices Package: zenohpico Architecture: arm64 Version: 0.10.20231221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 487 Depends: libc6 (>=2.12) Filename: ./0.10.1-rc/zenohpico_0.10.20231221dev_arm64.deb Size: 120638 MD5sum: 787ba70d21428e12550d1bc7aecc03c7 SHA1: a323be244163acea67c657f78555ed17dab78b7c SHA256: a9db27954eb430bbebbbb6babdb11663164cee4ab52055911078a5b4a835d137 SHA512: 1abcc0db64e2eba15d8944f7f4129ebd691d9ca457b338a49447b8c77cdb5ef60d7a86fef0d367c2203829849b2b88b43fe2a6d238f800cf831aa92f9285f6f2 Description: The C client library for Eclipse zenoh targeting pico devices Package: zenohpico Architecture: armhf Version: 0.10.20231221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 310 Depends: libc6 (>=2.12) Filename: ./0.10.1-rc/zenohpico_0.10.20231221dev_armhf.deb Size: 90628 MD5sum: 6f12d988dea148be40b8353a80270a90 SHA1: 0330c1bccd8f790e853ac897babfcc9edc496ed5 SHA256: 1c4074fc98081f66bc81435220316d9d8541593c45471dd91455b24c4f809baa SHA512: d4706f6ce8ed81e6b8aba904979f00ba0c8e8f3326ca25fa044492cef3f43a10c0b320b7bc1531a8f97da3b435cdab30d65baab9173baa18bc4da8281007ddfe Description: The C client library for Eclipse zenoh targeting pico devices Package: zenohpico Architecture: i386 Version: 0.10.20231221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 462 Depends: libc6 (>=2.12) Filename: ./0.10.1-rc/zenohpico_0.10.20231221dev_i386.deb Size: 138720 MD5sum: ff8b272b2386a6c21545a7cb4dfc22a2 SHA1: 8ad9a495988f319ab8e245b76ba671da887a0cf7 SHA256: ac553014af99eff96664d609060c6dbafce0a5e7354b45adb29f23a9860cc482 SHA512: 0310be73b56b18cb0b785d5cb8cfb71720ca65d6d1f0016f9135a991f5ea4c11f6b2f209907194628c9f93a2b788e78eae0c9527632c5ee1b44ce9e3971e7c41 Description: The C client library for Eclipse zenoh targeting pico devices Package: zenohpico Architecture: mips Version: 0.10.20231221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 414 Depends: libc6 (>=2.12) Filename: ./0.10.1-rc/zenohpico_0.10.20231221dev_mips.deb Size: 113578 MD5sum: 3e0c72e65ff4d5d56367bd7b8e49b707 SHA1: 4fe28b07426fa519103aea3b15cf12fc20a7b0cc SHA256: a03215f3a1c9f012e940ba592dd993773002fd7e6d9ebf016ef804be6874088a SHA512: 97debab7a596f9d835b134ac85094f31d1d244aefd518c3006ae7583a744193f691154d1b8438a1ff50efcca2e1efc86290ebfe1af33244f9d35aacd787ace3f Description: The C client library for Eclipse zenoh targeting pico devices Package: zenoh-plugin-rest Architecture: amd64 Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12975 Depends: zenohd (=0.11.0-rc.1) Filename: ./0.11.0-rc.1/zenoh-plugin-rest_0.11.0-rc.1_amd64.deb Size: 2382512 MD5sum: db02d888d6e5db3b5d3d2aea81cf33df SHA1: cf5ae4af2fde186dadcb5a63f0c9e6e921216fdf SHA256: fbd7646bb00d4bc6b1a395322da539dc263efb6b7c9b08c4c490832777cf152a SHA512: 0254a541ebd94fec96b14cc3cfc91e695309cf962f19f0b5ee73dcff01a0ec243a48962e4ff5a80fc3e9e060cc427d68384925a7bca7475021b3ae8fc51f742b Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: arm64 Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11329 Depends: zenohd (=0.11.0-rc.1) Filename: ./0.11.0-rc.1/zenoh-plugin-rest_0.11.0-rc.1_arm64.deb Size: 2138124 MD5sum: 1080d6f62357f43c0824450eaffe5d88 SHA1: 8a5423d774566b1722adfa5f387e1d4065f0a272 SHA256: 9a0a5248fb9e3f760812c8430ac31aab5638d19db07e3be73b833a3b07b858f3 SHA512: 4edd43bfdd0d4fbaa8553c8775f2b63775ef8854c6edde170d1bee933c320c5ee8bb419b294b85d089e99dc068a6c486b206868c9b8aa191281e355c4856ed7d Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: armel Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8702 Depends: zenohd (=0.11.0-rc.1) Filename: ./0.11.0-rc.1/zenoh-plugin-rest_0.11.0-rc.1_armel.deb Size: 1930792 MD5sum: e4e20e9f16487173538fd9764eb85353 SHA1: eeb01e18ae4e88c1bd0f854566e664a5aa12e0e1 SHA256: 2a2c4a311e502dcf236dace078fc838989753e2423bdd1a1e9d638d91f6be82b SHA512: 942ea1997664b7b6ff648779cbdd1812646305d0d96eb141073caf588c42b7c2794ce05e55756640ddce487953662ff9ba2612905a5d6c420cbb6bacae18bba0 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: armhf Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8628 Depends: zenohd (=0.11.0-rc.1) Filename: ./0.11.0-rc.1/zenoh-plugin-rest_0.11.0-rc.1_armhf.deb Size: 1918952 MD5sum: da03edc0291a69794be11470d1039a8f SHA1: cd802033731a79559b35c1bc1ba17e6d034c24ad SHA256: b6f028e8427e354afb0b1072a085b8bb47dc617dcf0799d882c6550c98131050 SHA512: 492e8fb3d238d1748168e0742a6e06fea99062b2eae67175e3ded49d5b4f92f562cf46eacdd2370d58ca7deb0177fb13273b98a7a8fb35b4dbb18f3887c7440b Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13196 Depends: zenohd (=0.11.0-rc.1) Filename: ./0.11.0-rc.1/zenoh-plugin-storage-manager_0.11.0-rc.1_amd64.deb Size: 2404108 MD5sum: b19085a350bbd03a8af520c7a6ab5c21 SHA1: d08ada1abcbc7626fbe85a567f9ad93bbbdf4e9a SHA256: 0346cbe6786105844903901ba887eedd1b3a7c9d6187e790d7938a187091e7e2 SHA512: 68fa80ec3969f4a0ead33fa027c6a03cd1bdeea1db5662ccb8a51ad98c6d8048a38a29187e1d2061964de0b3eb7f299e770821d0a901bc524e0da5e8a29bd19b Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11512 Depends: zenohd (=0.11.0-rc.1) Filename: ./0.11.0-rc.1/zenoh-plugin-storage-manager_0.11.0-rc.1_arm64.deb Size: 2161220 MD5sum: b4ce8a312d5b102b0bc1f531d13b5554 SHA1: 4911711ed714503e240f19c6743f61dd60e4d06f SHA256: f3e8e41ca6ddeedac6d9cbff84df586470d4c3498ec51b90dec5313c3bbb3fd3 SHA512: dd06da5494eb1db8a78eb2ac88e4d6c2962d6eaec33841497c203ddc3fbb23fb18ff61be3ef5e1b56b54ccb89757e35de5333c7b7c8aff2468129a66bf26ead4 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: armel Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8951 Depends: zenohd (=0.11.0-rc.1) Filename: ./0.11.0-rc.1/zenoh-plugin-storage-manager_0.11.0-rc.1_armel.deb Size: 1974656 MD5sum: a291360e40b2336d6be1c5bb9cee9453 SHA1: a005d08c7ba47bb692c0b0b23e30fc468392d836 SHA256: 5a7812cae49dcec2764644cf3467b78ff2a0974aaca97b6baec26f30799252bc SHA512: d5432fd13f2b3566a559727f2b0454c25e1258146b7f1bfdd7424f3fe37aa193163b2124d33860a5438e41dd52586fc5c27c57418130a648554ffff3e9366520 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: armhf Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8868 Depends: zenohd (=0.11.0-rc.1) Filename: ./0.11.0-rc.1/zenoh-plugin-storage-manager_0.11.0-rc.1_armhf.deb Size: 1964580 MD5sum: 2612b60c25b418e98919781b0958c994 SHA1: 8d00fd2992ac0b566b2397e74f9d9a5adc4cec8a SHA256: 1cc5a56d7ba56682fd5c77618c10ece7dff4b6b023daee4e2ae3c011edc51cb0 SHA512: 76bece1777b0ebbef492887d9e59ee91cb53d2c773fff80f4dbebd2d95867268cd24a76768802af012e42ac73eb98d24b82e8f99cf29baf25e9375bfdbc39beb Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: amd64 Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=0.11.0-rc.1), zenoh-plugin-storage-manager (=0.11.0-rc.1), zenohd (=0.11.0-rc.1) Filename: ./0.11.0-rc.1/zenoh_0.11.0-rc.1_amd64.deb Size: 17272 MD5sum: 9f1310bce8adc10c630aa9dcec022be0 SHA1: 9d8cef2bfd4df7586563a0bcbe3e5685e27b7205 SHA256: ff291e13f9765f9a48f0781182f0648912f9334f22549cc4f7f813fe70971ce6 SHA512: fa6e6bcdf3a2d49713c59371908ed0ae4eff56fc946163edada1a98412a497a3d12a4905b25be05616a18a96516711d9a7155ba8773d3c0f81db24239a45ebc1 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: arm64 Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.1), zenoh-plugin-rest (=0.11.0-rc.1), zenohd (=0.11.0-rc.1) Filename: ./0.11.0-rc.1/zenoh_0.11.0-rc.1_arm64.deb Size: 17256 MD5sum: a0a4adad68141cf9c28f6908407183fd SHA1: 913e2bdbd8d784c00218e9ecd1622ae7bb9772d0 SHA256: 6ec69513785251a4737a751823c62a2c1c96da73a766315dde0f730c8c7b231a SHA512: 4262edfefde08bf2f9a4f93abbb1abce7532c074fad0ba0808c993d8a1fbdb947c9a494b56b7e5abfe2f8e997d7b9837a5ec398125305ffbaa57114ff9993460 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armel Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.1), zenohd (=0.11.0-rc.1), zenoh-plugin-rest (=0.11.0-rc.1) Filename: ./0.11.0-rc.1/zenoh_0.11.0-rc.1_armel.deb Size: 17256 MD5sum: e88d81be6393996053c15465f1084bad SHA1: 6bfe5e7c6b4de70ffea5310cc26631ae8d286b40 SHA256: d76e1b46703790056d2f4181df4d4052718e7c2ecb469d245a1b644c707eb364 SHA512: 9bdc490a28225fe29822d49829cb3f87b3563a741a674563df04f727636d549745d11becbdb7679bd3e9b9b628b6573e9249a06129e2bbdc59e1f74302c9503c Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armhf Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=0.11.0-rc.1), zenoh-plugin-rest (=0.11.0-rc.1), zenoh-plugin-storage-manager (=0.11.0-rc.1) Filename: ./0.11.0-rc.1/zenoh_0.11.0-rc.1_armhf.deb Size: 17264 MD5sum: c77ee7296c12f85998ef9d93170099fe SHA1: ebee6092088da1ccaadd16e0517de53b8bb90977 SHA256: 062b2e6f30114c3c645bbcdd4c7b6b0913a9fca6d969138906285c396076b40c SHA512: 07dad3487cd2b2aa378d9399cc4e46cc82d18197c85c4a86f52f846fab1554841a753166e6bfa96a54bc6c918a54669e8bfb8093907b84a7cc5d8c66068863f4 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: amd64 Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19689 Depends: libc6 (>= 2.29) Filename: ./0.11.0-rc.1/zenohd_0.11.0-rc.1_amd64.deb Size: 4670832 MD5sum: af0aad41eecd2d5a2e27111552e5023d SHA1: c02867a7718a32f3bf8086726247b30041cd892c SHA256: 67dce6aa8db8b0283884caa02676456c4e267a416118b17dc26a6ad6445cf74a SHA512: a8eedfb6bbf77adb8d4115823374b41ea6db5e287ee1319b06bbf44139e3ff698ccb346e75f7159140c4ebd7ef66c9362eb56598f8f0bc08afa74e728672b8ef Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: arm64 Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17046 Filename: ./0.11.0-rc.1/zenohd_0.11.0-rc.1_arm64.deb Size: 4144788 MD5sum: ecbef038f5202bec8993833e52ffa443 SHA1: f28eb6add400df4069947d600d2e3589de484672 SHA256: 8896722e963477f9598a71bbbb62d97d2c8b510c53cffd71cc40dd8c95b8f464 SHA512: ea9a0046561d615a13205be76bfc83991b72dd32b181d8eaeb9901dc17551de2155344e6f7167d04f042475ba5543ab42e230dcfde1d62125c964e9bf39f8439 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: armel Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18558 Filename: ./0.11.0-rc.1/zenohd_0.11.0-rc.1_armel.deb Size: 4548336 MD5sum: 6e644657b6dc11eaa25a14c0788c6c84 SHA1: 57993e7eb4e192f0c7552936e35bdfd739782db7 SHA256: 49202f9e728bc9688bb1288deb4e513bae13838094e3e33af524a619d6fe5eea SHA512: 6a239e3cc36bb10f415eeef475294867f82515fe4a2768503e6cd8672f78d06ed7e7f9259ea2cc4ac3ab81d62294ccd6424deaa4cb847bedba4409638ac5d488 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: armhf Version: 0.11.0-rc.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18311 Filename: ./0.11.0-rc.1/zenohd_0.11.0-rc.1_armhf.deb Size: 4604488 MD5sum: e146594a5159604e4a8b2a514738150c SHA1: 17396d8b9a422b917d20c5369262502688b52bf3 SHA256: 78a39da695fd7f816b082bbb0ccc7ef40bacccd65a23822b0062681d146574f1 SHA512: 49afec7b51dd4310f249eaf876267f9666e5fa8a15542d8d91f5db8ebbe14dfc27b310b8efba8fa1e72536f26f160083c7216d16cf63f389ec9a29f718afd6d3 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-backend-filesystem Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21952 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-filesystem_0.11.0-rc.2_amd64.deb Size: 4690956 MD5sum: 91934776ea06d51e5d55b9ac5e9bed14 SHA1: 975b6a2c989ed40753c91f84353962d55906fd0e SHA256: 5c48255f4f7e581cc7ed4525d5985060dca575ccfb38d783d0e6bc03352e24cb SHA512: d21cb8f855b83ade038eda367cd2cc3dce4847cb8f59b18aeb3e771f28b9403c7b88ccbfcd81f823da0ddd086452581fd69962562359ad70915b02700b751a51 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19685 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-filesystem_0.11.0-rc.2_arm64.deb Size: 4206160 MD5sum: 30eb26bf43628e07183fa8106ea6fc2b SHA1: 845e52a102f2d4d282ed06256aa4133b88e85346 SHA256: 1f0a7be528018592b6d9d96c03077362ef000f7075daf90cc9f6145db9fe87e7 SHA512: 470fe7aa0f1bb874d65500f4966b95586cd4c65fb4ea22a9ac88d1e912c836b1ab31918ab1825690f3bcc2a04037e6347461e661903e2e0703911600c79a963d Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16553 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-filesystem_0.11.0-rc.2_armel.deb Size: 3909368 MD5sum: 2a9beef1914ec227de621e7216cd34b1 SHA1: 2d5f106bf92ba1182f73c1a77a24072cc5e3a9b9 SHA256: 2971ab488685fab7c28b5df3e14259c9d1b9c7167f505e175e63f502b4824bdc SHA512: 85baa695fe436231232798f9bee64d97803a01d0d6f3a7007b9d1f103309a2fd1eee2aa085de75fb668e70c5ce0a57e8d2b076a5f0d78af5b593449c7cca2059 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14817 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-filesystem_0.11.0-rc.2_armhf.deb Size: 4005968 MD5sum: cd9058cc7d7634b11995d5321488cbf8 SHA1: d03393e3c4dcfd7009239a12b7825b617339a8d0 SHA256: 8f2e85a4c8291699fba5d0889540680fd22c94e22e9f58e9ac683b52a5a2fc47 SHA512: 07c747599786b7c4c7781ef127ab0e323930493d651c866e57cc35aacba163327535f3a16a9cacc7ae42a694f2d403cfee2a1f9ba1a9a293cefce6545a018319 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-influxdb-v1 Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16498 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-influxdb-v1_0.11.0-rc.2_amd64.deb Size: 3308632 MD5sum: e9be1d76e0747084bf15f75a24931b64 SHA1: d7151dfa6eeacd39e63c07825791fc28cd895174 SHA256: 324afd5b022eda61a06e68711b0283647606b5d72242427d3636747bcd50d678 SHA512: 91d088f33cb6e2d4e2bdf7c87e4f7024b2cd964a0c77c60e356cf3ce3f9905ec8bf19e28badf44bbebc91fce1e43c08aae91e793f13bdc9df350ce41f794fc7d Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14985 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-influxdb-v1_0.11.0-rc.2_arm64.deb Size: 2993156 MD5sum: 47afc88e9148be10ad117ad0be892757 SHA1: 8b2e87e9b9ec78b8189a8c48948bd9e1dc89ef43 SHA256: 64fb0965ee05bf21175343744171d4668d6bccc432dd3b4ffaeb05d13b49ed55 SHA512: 5756fcee580ae6fa7649ba94a597306783bc676874c1538ec4462226d88ba7f601e327c2e3c8ef8e2f32e13e7b9dea4b84e83356c2bdea05029a1b97f4dd84f9 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12568 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-influxdb-v1_0.11.0-rc.2_armel.deb Size: 2716964 MD5sum: 514713a3f1a2891acc481483f0f81f5d SHA1: 11868ae34b110528b1c13f56b2b09f89ce6ac61b SHA256: 841778c1fbeedcb53b7b9ea5245f31894097afb612c99a240ccfd47afbb870c1 SHA512: 34b6f1a6daf68a8efaff95db435681239cdaa3cc645daf2d3b28fdda9fe050a383ebf938531acbadcbac06de58462995087ab4f69bcd974537e05d310af56106 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12488 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-influxdb-v1_0.11.0-rc.2_armhf.deb Size: 2716448 MD5sum: 56a0b728d01cac03e3c72d47ca57cd4f SHA1: c37b293c116531d41eaea2fede55fc36d1a9205d SHA256: 70f02c9d0b104771ffa4d0ce73813c20c17dbdbd4d6e64bc43e11ea1a1ec1ade SHA512: 49f54ebb0be8c14f20def22a5cea3c93b67fe0cf8367a358b46f52798852a3cfafa3c6666ebe8a03cb0519e939572331c04e3ff8db42a51b6a6c7c9aa27b6e2a Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19786 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-influxdb-v2_0.11.0-rc.2_amd64.deb Size: 4113804 MD5sum: d59c6bb5e799b8f84c0c91420a7c2321 SHA1: f9e1f402aaac7b8a4931a3e12d7bff4a4e0fad75 SHA256: ca69610c0957d3e4b9ff3ba8f814f92be6cc8ac3967423f6e3ff2b9fac368bbe SHA512: 2917d26dba0a320ab2836183f72cb1c81f1847d96bfa0e9d6605e452a20385908e3d8abcd16b9e6cce6fa3a1bf6a24a008ccb3de8a7e0d0241c49587e948bc68 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18366 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-influxdb-v2_0.11.0-rc.2_arm64.deb Size: 3788904 MD5sum: 26ea3a862e49f9a52c48ab2eb162db0e SHA1: 526feb19452706f72ec3ef9b0382f9c4e4cee91f SHA256: 52fc14f62836be32d78f5750a22b905a3ea25d6ca7769edab844cc2a8e7912f9 SHA512: 7ce744505c204b083031082bfbf29dd7c47a4b0c9c6f9507bd88de00e082df81ab3bada5ad303f968147b5a562d93a2f7117d961ace97b54589b8a8f01897329 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15670 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-influxdb-v2_0.11.0-rc.2_armel.deb Size: 3482156 MD5sum: 653d007ce07182c2147a50d7f62ae4ea SHA1: 7564da81c20b1b27ff42e8300f7beae9ac47f5dd SHA256: da382ff4c286291904429f68ffa77f2e3d9d6c26d2fdeaa879f396f1e6af8f2b SHA512: 04ee36cf9e82eb0254d51287514cc688f2b21cf4415482d417891b65f7f114c8d845337c7884b0aea0ac1248267d77e9cab026831d14ea763f8b2b93618a916a Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15548 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-influxdb-v2_0.11.0-rc.2_armhf.deb Size: 3488480 MD5sum: 36ccc042bc7a0ba9ecb27025d66d49f1 SHA1: 1f2e7c9d7e5581480d917111560fc68da2902797 SHA256: 97d53ef05be644551d85440ffb251cdfea6b52c4fa3e90ee5c9fc15171a822ae SHA512: e84f630f2518fe237597551d2333cf187035dc0f29298fbf0e7c81e3f8d0c130aa5937195703c413e4b51ac00b195138c2cc5c11f6854721e343c0a2e2e6bd00 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-rocksdb Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21705 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-rocksdb_0.11.0-rc.2_amd64.deb Size: 4652232 MD5sum: cda8d50fd1114f71f018247c8fef3a2c SHA1: a6c8524f204b036956c174ec9d874432e0ac688f SHA256: dc1d7896353cef06c018da2a4cdae0da119d5a336a3903185c40458062e0ad1b SHA512: 558bd3f30bafb7116e7c9ecb6381d7bf75db31c36c49ca76722a0303d84a2c7d8f4edf678d51fc7b20726e85fea950edd2bc27f76b1a0da8c522770544fc1651 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19334 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-rocksdb_0.11.0-rc.2_arm64.deb Size: 4152148 MD5sum: cb33965507fe0fcede5afee29451ce0a SHA1: 5c88d3f46996e505566bb783e0dd28c0ae85d3fb SHA256: c9cd307e64c4d14dce3eeb71c55289f374dec1b11ec3b5e56334f789baf36207 SHA512: 20c70cf6a2444b0a1172d41b284843b91580e0f87b354c0eaf8d45bd17e4f7d800318506caac5188f5aa4ab321d7248d0bb9aa62bc03d644c2913e549e069a60 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16339 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-rocksdb_0.11.0-rc.2_armel.deb Size: 3870416 MD5sum: e33dd3b036ba07dec06dd1e22a9982e0 SHA1: 31343747536b277fcdf3ddda63c63873f9408560 SHA256: 85766df31f3a27d7cd8a90d7b93b82996aaeab5e2733fda3e88f905ec34f8e6a SHA512: 362907ba4e25c5e720b34a1b308796c8c926cbc1104df23d87969e504d450f748bade644db32f146f85f5a83c3109fcc6e0ead00f370d95a7e5861b58ee32041 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14566 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-rocksdb_0.11.0-rc.2_armhf.deb Size: 3971744 MD5sum: d16849dd41c4f6d656ff3945dd985b3a SHA1: 287ae9e01ba0cbf5e420fa8c180bd2ad2f346aea SHA256: 969953a737f35f339857bf3c380621b2c47f0b9717970d692c3349de68af7ed8 SHA512: 8ecab17a46275b5c7c890a9c2e7ee2d63f02329dc380f88657dd5551de94417933a14eb9b98ac3d147baf49e4472980ff3b667272ad0669720e9c6eec753bc5f Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-s3 Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26485 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-s3_0.11.0-rc.2_amd64.deb Size: 5253244 MD5sum: 5b8ca0d60f3249884e3422d718c26384 SHA1: bb19737d150f3f3a4d23d52b970bb20ed588fd64 SHA256: 783708cc81b764b151570aa68ac5bab4ab154515ee66d28bf39139b4b39f4e8c SHA512: 9d508846fbadb34875fefffde5bdb5737a2e072a9248d931f36222b929dea09ad93df5a41a51afaa1ec34d183575e99302ef486f44f6e34999c54a7e2658d300 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25029 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-s3_0.11.0-rc.2_arm64.deb Size: 4899660 MD5sum: c7563b5280cfc305815d422148d77d6f SHA1: 444fa7a4dd4a3fc575c48ec6cb85077654d00bb8 SHA256: d09a8db3b1cedaf90eeafceb082682ec3224b098233c143d360d9ae9ae43a5c7 SHA512: 07fbe64212204fbaf949f1d4368f73f5603c39746ed61e02d16fc285e7a25ac30f1946b0844c38c169e4059069177cc4112968f7d779f1e198bcb6cde59e4256 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 23453 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-s3_0.11.0-rc.2_armel.deb Size: 4751456 MD5sum: a42ffa816d37454370bf2ded036f7204 SHA1: fccdcccfc6a691c75f292b40c1ac1e21abfdd151 SHA256: 552bffabaa48093ee59c717e8d1b4d40a11c471b11208c1ac6a3ba6fcd8bb606 SHA512: 2150c8a7f3bd02ad0fd6e92f9d05a119e0a14ac6961787acbc0abce1ec3287d3d527394b40b9768e73270f5e91226bfa418d3882a567785eab277cc25650d216 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 23291 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-backend-s3_0.11.0-rc.2_armhf.deb Size: 4795468 MD5sum: 45158c4b6e0a7d057bc4c7c68fe9e367 SHA1: 50f20b1245629735e2acc3fb753652e3c6a5dead SHA256: 1f061e47e5173a3aaca160b0824b3a7080f7c4c9488e9a24d4b16fcccb333241 SHA512: 1ec38398253017206cd8b780b2a6e9d2df78488153ea48e700eee689ab5f84f8fa6129d5ec16b7b4caf4153f8b75deb1e5adf4b4d20ea22390ea085e00817a90 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-bridge-dds Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21774 Depends: libc6 (>= 2.29) Filename: ./0.11.0-rc.2/zenoh-bridge-dds_0.11.0-rc.2_amd64.deb Size: 5351348 MD5sum: faff6379750f1eb71fee6fb8d55a4914 SHA1: 8114f59e1168e3876e7c2665d119ec338a7da33f SHA256: 52c381c676b1595ee2f7bb4ca501225f16be610a4068370dd62779e80eb700d6 SHA512: bd7c36a398c65ff61d8e99ac88bc06180ec655532a7463f9d81588f441f6513760a84ea757afb7c3610a43cfce88db0772a81d20f96b29a4eed52f0e64194598 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19359 Filename: ./0.11.0-rc.2/zenoh-bridge-dds_0.11.0-rc.2_arm64.deb Size: 4795304 MD5sum: 2cf07f05ea41fa79eebd9f6d777693bb SHA1: f9ee4d0ddc0f6dd23463fa95a9500af562c2e8de SHA256: 52bda4655dce1f3c3edda540a94d7d40f733d92217f5286866b2bcaddecdd1af SHA512: ed0194863bca713fcbbc7f4e3b1eee980ee07af60ecc163125af2cd4b0c851926e1eac76f3c99817400aa65fbc87710d06cd0d815e258a66320fcd6ee6941593 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20536 Filename: ./0.11.0-rc.2/zenoh-bridge-dds_0.11.0-rc.2_armel.deb Size: 5115156 MD5sum: 25a04d3c17e3145b39962758236a984b SHA1: 7de79719aaffcdff7a6b07315cb81867b0c16491 SHA256: 4a86106dd71c373d229919febbadfa1e7a70bf5abcf9a7cd0e3cc787dae1d112 SHA512: f5636b89866cbc348c9225b34e3d95bdbef8ab93dae7298dd0b6a0a684e362ff35c9a01e7f8ec74bf89612e6bf285e0077a8747c8ca640d020ec61c2e68eed8b Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20041 Filename: ./0.11.0-rc.2/zenoh-bridge-dds_0.11.0-rc.2_armhf.deb Size: 5162000 MD5sum: a2e1830bb2140976edccdecc3f7e0776 SHA1: b49b6c7f47019350b053273ec836a2b55cc36dad SHA256: ed8bc7bba598db11d2abe3e2f84e5d97a7eac3f97d3c87a1773d50c4d2552864 SHA512: db36e93f338977f61a5aa2b331d8a601a4f1aabe5443d0b43fa1525a9972f323a2626663c006dc14c92c91f68ced67af85c85392115b44824bfa10b99362e9b0 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-mqtt Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21369 Depends: libc6 (>= 2.29) Filename: ./0.11.0-rc.2/zenoh-bridge-mqtt_0.11.0-rc.2_amd64.deb Size: 5062456 MD5sum: 6d53c05426c348b743f289d02aeb18ff SHA1: 821e4ad0e754d4c427dd5e4dc5e2bd9961971c6a SHA256: 92ef54860483a863e9bcdf5cf63dea22d496d808e1a3cffb4291a05b08ebfee0 SHA512: d369b5364bd6c750c51fe0f95ae6be2b8917f6d2d7b1672027be5d37bd8cf4bf9528330bc51fb0e39d434b1b6deb004be25ef840bd501f0bd31b341ebb18267f Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18884 Filename: ./0.11.0-rc.2/zenoh-bridge-mqtt_0.11.0-rc.2_arm64.deb Size: 4521080 MD5sum: e3ee4cd75cbb6117341439579e2e80ad SHA1: fdb45e96d644577123a41efb4b8647fd69ef7edf SHA256: 3c6f23e0bfb534bd32205a2dfc2176afdbdbbc94e8cbe68366105983bf575bce SHA512: b687bde4229baa57b32f41657be3895e3f2a54e33a0f026a5484c0d14d61af46e9dfa06d9ebe07e1887c42545c46572a62f5903557a289f311eb931018cf032d Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20240 Filename: ./0.11.0-rc.2/zenoh-bridge-mqtt_0.11.0-rc.2_armel.deb Size: 4862464 MD5sum: 226b182070bb14ecd372a3858c6a355b SHA1: 04f6d5602d66bb837255e10f86bb10b7c73f87df SHA256: ebed9d1820b7dea50c85f875ff56e9b04fc70e5a6ee39c7243ed4fe50ff8d95f SHA512: d8d865ffa90e2ae25640efebb4f2cfcecd314ef0da6f30506047ea08a3516a82be9ed1f3063abb77213c5eafac4f32d39f35eeec640cd7e99e5558bf0c4ad197 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19977 Filename: ./0.11.0-rc.2/zenoh-bridge-mqtt_0.11.0-rc.2_armhf.deb Size: 4891336 MD5sum: c66c48cabccda2160fae0e4fc29cc674 SHA1: 8315a955d0ca9dfdb3c13f10ea35aef40f501aac SHA256: f7b22dd85a61305567dfea02d7c7250454ceabae9486d4029064871db0d1b8d6 SHA512: 35728cc617d49cd67ac134fcfcfe32f0e8470aa7d0a008ae0b50a193a0cd08add92ec42d614cafb9dbb39b09c36e748f836042688dd8dc5427fd1a32663179bc Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-ros1 Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 22845 Depends: libc6 (>= 2.29) Filename: ./0.11.0-rc.2/zenoh-bridge-ros1_0.11.0-rc.2_amd64.deb Size: 5453284 MD5sum: d476cd8cb632a3af122269151a1d459c SHA1: a9c62836f659e7cd5c4882813ea575abf1fd0692 SHA256: a79432e6523d51fbe3c5aa7fc03eb5ec9759aca2ef428ef4444411661d312391 SHA512: 12cfe47b1885af7af927ce75de28ac081f5ab502fa472922b158812fa08855b3641af593244dbcf5ec711f4792e88267b263ca1789e799e4f84b737ecbf71952 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20276 Filename: ./0.11.0-rc.2/zenoh-bridge-ros1_0.11.0-rc.2_arm64.deb Size: 4879352 MD5sum: f450bd7ba695f1f1e563c31286a20435 SHA1: cdcabb4c976574bd321c033951e20e6ca95edfa7 SHA256: aea7b35464a8f66086b2de455dc9068166ceae057e8feefe706419432a45d3ef SHA512: 5fe0ca1babc579bb18e4717dfd76df5ff03e4412cd77f72beb5af1132826eee4239d7d521d5ffa638f8ed6c961224f53a960e534915a7068bd7f96344bbd3f40 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21637 Filename: ./0.11.0-rc.2/zenoh-bridge-ros1_0.11.0-rc.2_armel.deb Size: 5250668 MD5sum: ab1d86f239dbd7d7d36a803a31c82314 SHA1: e03db351dd1e75c3e6ff32bd32d4335abdbf2c3f SHA256: c572c965492b8cf690e5a2751cff80c56c03bbfd401bf6e89143a4971168560e SHA512: 558da9127424a0965d4fa4e229539ad33d60e8c04254d57636ab26deb6d534331d50c67c820480ad3bf6b0847b3677b7c5c802d6ea5d82f26cfe1a00e5178162 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21323 Filename: ./0.11.0-rc.2/zenoh-bridge-ros1_0.11.0-rc.2_armhf.deb Size: 5280256 MD5sum: 3a49fb90407369f3eb6ec4ad81ad9c14 SHA1: 116bb1562257986817a324d8d91c49e42ba28103 SHA256: 23504a8ec101a1b48c8091ad453d5e5cb75d1ce67ad3ab48b55176f5a98e0bcb SHA512: 86afa9ad2478d9d4174b8013f590e52befe321359dabeec818f8ec701ce68cbc473957c500b09078884e4262fc4885fb3b05d8db5ec4fe4846ede07034f243cb Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 22364 Depends: libc6 (>= 2.29) Filename: ./0.11.0-rc.2/zenoh-bridge-ros2dds_0.11.0-rc.2_amd64.deb Size: 5469632 MD5sum: f3f27a0dee0086689814bf238272a47a SHA1: fb14d9bb9d0e9ab0ea9e193042b868b78469c6f6 SHA256: 9c611dce551d211b0856e5bd5188e2a71834fd76bc9626ad0da38b8300eb3c68 SHA512: 9a846e3f9676cc42d64dada49aea70121ad26c9552355d69c067f7399dc122d1edca2bc45f9c2f7e61296c71500aa1262c140ce12010d7cac5247953737a99f1 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19942 Filename: ./0.11.0-rc.2/zenoh-bridge-ros2dds_0.11.0-rc.2_arm64.deb Size: 4916128 MD5sum: 65309409b75e1d645bd8e973da4651e5 SHA1: 713b8c22e1e2330169d24fd2a83bce7b690b3f29 SHA256: e4a12cf6a8675b9195b943c0628d6a0d7756126d218e0bdda92814551d4a339e SHA512: fdc1da7fc8e850438cae0e67b0e716ab27eef4b5a4847f5761db42d6f5c5842e7d96e958f7d2a70fb5d8ea4d95b8dcb10e3caa56e3036205b71a3f09fec8dc18 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21132 Filename: ./0.11.0-rc.2/zenoh-bridge-ros2dds_0.11.0-rc.2_armel.deb Size: 5243592 MD5sum: ff59148d2a9610ad6d349e78d6dff013 SHA1: db9336960171d78237c8a912de7cf89ab5f98fff SHA256: 5506d8567ad8f7b26290b4c6751e6795c7ee8a3e2a8b15ba7257a134bbb4981b SHA512: f283546cbde868792542b9f84bccba02c891e6452618d9ddf7ba8974dcb532fdf13f6048fa675d5303ac0c7000a30c508314f209480c59a993962fc68a52f826 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20631 Filename: ./0.11.0-rc.2/zenoh-bridge-ros2dds_0.11.0-rc.2_armhf.deb Size: 5298364 MD5sum: 381c55f57ad8c51c352adead921c6d68 SHA1: e3122c277386341a1f30c692be7f1420ec9dbca0 SHA256: bbcd4e0ac895ebf3f04ec032bd2dd0e5cb9f5a1c9d1570925d65adde96f31063 SHA512: 21c878d276d3640902e6cf16a7db483de846aa672f47d5f2b43d0874219e9d777c0349fd8be7c4689b0409681c38d2de33058304c2bcc20bfebec750ad6ee3f7 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-dds Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14133 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-dds_0.11.0-rc.2_amd64.deb Size: 2741172 MD5sum: dcf9ff4172e8f76dcd43ebb767e8f40a SHA1: 2337a4d6fc331ce7e9bdfaa7ce253d6fd9fe8f4b SHA256: 5a23166e074d75a82c8c3f032e46a37a4b46918e7655e48add6a0502d4cb3269 SHA512: bb2ecd2120661dd969668a1dee03673c348b9032756166fcc6d5495ac639d94a6afbeb8568bcd606a89adce62cc60accd00a5139329fcd883d30797b49dcffe2 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12511 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-dds_0.11.0-rc.2_arm64.deb Size: 2472752 MD5sum: d0ccf826fd79025ca5e7f7c5d1924a39 SHA1: 4ad1567c45a29e4b0dd0689f6fba9509c99fa229 SHA256: 140ea6abff2254c127e26c79dc5c709abccc47764c6e6a6ed4346634e35d5837 SHA512: 9ac91d7516f6e9e5dd47c09decf0747e759d89d0d235e119e871cd063645c4469fb74de8878db31122ce07ac89d0837797aa8d0237c84eee2a46c193c6147764 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9772 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-dds_0.11.0-rc.2_armel.deb Size: 2251936 MD5sum: ac8a64fa1ee4f492505a0ae16f01a1b6 SHA1: 026edcd80b97039b251987258acf8bf280bcdf6e SHA256: c44643acdeea36a205d48ccd1d607a39bce9b7279f65312c6c6fe199cffe84ad SHA512: a480a61d9f40f6100370f67d706b8ad4198b58b9b19bf619bdb5ad6d44bd5515d6f7a874139b6ef6394ce6e8e5a16d79026b5a5dd60500a159a3b0fb1321172e Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9448 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-dds_0.11.0-rc.2_armhf.deb Size: 2255072 MD5sum: 0b6cc52057acbefe7725893d991c4285 SHA1: dbb8147b434f61767d272876b4e6023195530fd4 SHA256: cdaf0b9167bdf66c8e113094723bb76ad63dd3e01aa7346f3fb21a49f21f7a02 SHA512: 1f553d902641f6c49d80f7fb843a83e492de47c40ef5c8c38fdd06625a898afac59c85223acf26367976d29b6f21080a6fdf6d0e0ab3e0dd7f9b07b0d0dd4e1d Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-mqtt Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14769 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-mqtt_0.11.0-rc.2_amd64.deb Size: 2938680 MD5sum: 34a9696ceed4545ce843968f99bd64c8 SHA1: d1eac3e4a5c074837f768c36b8ac8944ed3ebaaa SHA256: 6b37f1d9573191b736b6bae31e6dad4f4e0bb22c9c5a1f09418a9417048903c5 SHA512: 0d80abaff4dd06451fd7e360fc0c120774960dd4d4083a848c4d054c29903072e976337a81492ca7d0b68f39aca2e4b36d0fc342b41f327b470b30f8942e0ae7 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13015 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-mqtt_0.11.0-rc.2_arm64.deb Size: 2616804 MD5sum: 98676a3686664afaac3a050a38b97a0b SHA1: 1efa68aea5df9980e9f1636f2bca059098975575 SHA256: ce0968b645bf56fdc012570e2d93bb88e793801ebbe02ab85d8db992b72d2f42 SHA512: 38195814d85e16c03bd4f493879b0260ddf8995b2d050a19115592f7d6e6b39df3a3e7728f11ffd1ab83a4e3367bc08037a0e1adcdb3c608c3eb3d3b27832e49 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11167 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-mqtt_0.11.0-rc.2_armel.deb Size: 2431808 MD5sum: 601a024276d602fdb38a592b8ef218fd SHA1: a17af7d2ee06efde9c86c18e5581b8a80a754b2f SHA256: c3a07675a25b5927018fbed724a182b51ff23607d9755d2c89177b2c54f0589f SHA512: 4e94e7c506f1cad6c34ca83ab090e84bc94121497e827db9f21fe69a906de4e4785df668aa9d5494b84ab662ea361be3147a52fc1ab1c2d7467cd5a3af55e296 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11075 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-mqtt_0.11.0-rc.2_armhf.deb Size: 2431360 MD5sum: 7f7753f4399a57947693356613d49b31 SHA1: fe05f8a75b5f6d0a387a1e8bfda0195dce762efd SHA256: efa8912fd159e9171d30a411cbc4b7a5cee22af6c0ead9ba73788ebc76b2f3c3 SHA512: 37774854343872af2f52716c6da4959b4bed2c949d3c90892abd66ac7d0778e3ac3b95a2f390794c1ce0f94ce8a2e662a652e0246e90434a10cdf3ca7394f78b Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-rest Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12975 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-rest_0.11.0-rc.2_amd64.deb Size: 2382428 MD5sum: 49388113d0c8e5fcd364d2fd724bb071 SHA1: 2da939a7e1e70421a82957801e109ee941f3a1e3 SHA256: 714860268a035cc7354fa4fd065eedf4feba7b87b75541b3eb9cfeeb1759b023 SHA512: a7d870727290291c661d425257e6f6a7c4f2cc6e5dca33dbb25e79ed78b77b41573c54952e42d305d980f925738f100c4d1795c284dde6a3ca91551072cef41f Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11325 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-rest_0.11.0-rc.2_arm64.deb Size: 2136836 MD5sum: 8f2f3e63ad7245eef3bd8ac2a864ee77 SHA1: fe511b6f4266a57c6e534edbc4f8f69c3a850e85 SHA256: 08ff3f176d0d5f73d638988b8e05208159a3f5d6c804b28b650442ff43c01450 SHA512: b17bf69964a5ed53043182725bb93b859eb226a522a95e90da511c37305fd69f0fbe0bfafdebda3e772e15116ba35d73ec9a02d6fd4a57a8a40a36a21ec173bd Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8703 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-rest_0.11.0-rc.2_armel.deb Size: 1931844 MD5sum: 30f2428e3b076fff0c6795a12ca105ca SHA1: fab2e87f30d0ace4e54b9e66d6bc598ac081ef1a SHA256: 2e02098b7d87a87632b35545deeddde00ad4718d531fb8d5c1c4d6ed3cff3054 SHA512: ccf11daef023b72a0f7cc56e2c61e2261d3ba9b4d435848e2e5de1a387c8ed4170dbeb9930b56a9d42b06964f556e88b0131f6850c3a14c85abcb7b21c2f0eb7 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8628 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-rest_0.11.0-rc.2_armhf.deb Size: 1919140 MD5sum: a8b825d0692633c1cc0ae4eae89f2b1c SHA1: 044c0c939f67f5f3a964361aa508a3c8075550a1 SHA256: e0aaf00baef570e6f679848e375d80f36e8ebb79fe981c0a305af36c5e1bd209 SHA512: a47985d6a67bd6ae1de8e69d754c3702e8581b9270c54da50a26aeb33ee42029f16897cb29eb94671614b90af7997353af3ac1ab9c48be221e9e51480144803d Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-ros1 Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16751 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-ros1_0.11.0-rc.2_amd64.deb Size: 3360716 MD5sum: a1f481b139af20de2d1761275a792fa0 SHA1: 2e17d46360b1fb61f22fac3473eac94941417adf SHA256: 6991ed0b8a9176a399506e583ad31d87433b4240b6a47295fbefc09af89fb5aa SHA512: 9a546470b6703756308a882a26915e05836f7d23743613693185f5534072fbe1e0ca0377ae577702e5a7202ef33d870e2625454b319030617927a5b24b56fb3f Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14927 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-ros1_0.11.0-rc.2_arm64.deb Size: 3068564 MD5sum: 25378e2066de473233738b6b484117ca SHA1: 22340ce00fad3ef1f83bb491fd4f7aa06fc7a570 SHA256: 3f1e8037266602a638590845a1be130b8bbbafd34e35cdf846cd426f9a10c999 SHA512: c334491a54d315f325234192f5a19e583c8e424b5c3de2663ca09f02fb7acf85e3d94fb2147a97fdee424fb5dd8f790c8224e23bc6e2857dcda3ad38c0be7b53 Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12381 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-ros1_0.11.0-rc.2_armel.deb Size: 2900224 MD5sum: 2bd4b43b8d99269414acb2ca4a69792f SHA1: 03ce1e34901be31b4b5baaa712dcd8f400adedbd SHA256: 70ed1a5629d41f6de11ac79ee3e562df749207f02a786679a8268a71e3316da0 SHA512: 9a60a22f1c5a181f714c721483d33ac898274d5ed5a2d071273470972aefc7fb75a67953a09216776223aca45f6155c1b6f8dd05c1fbc80ea71813838fdf6fc4 Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12206 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-ros1_0.11.0-rc.2_armhf.deb Size: 2873748 MD5sum: c29831ca078c2218e2105ec91178b8e0 SHA1: 6c5f4d9c0d7861c2dedbc0fa5e0cabcee61d00f3 SHA256: a3cf3b5b9b4faa7c8c7ed5ac16d6da1b71c56c9cf9f07b48274fdf70f9e4bf5e SHA512: ad403a8bf7e728c449703ffe27cc5472ec556ccd0ff14815f1ecce502d270fcf9144fa1016a4f358f5d41063c9310132003dd7c1dd7a6d424d28554ccde51dc5 Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14779 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-ros2dds_0.11.0-rc.2_amd64.deb Size: 2864904 MD5sum: 5272921307a3516aee97a631f0f7e47d SHA1: c86f6b6abd097fdeea2bd5e4cbabb038bce05ced SHA256: 3bffe6e76934431b4a2408e5bd42f3259ad590d22ca98b486d6060440b30a250 SHA512: 312bead297b9040f233b511bec375d5cd6bd7e0ee55512d664bc0770a3576ecbb52c00b5469e0842e2cb3b16f98e4ab1e7f73c80e25c4bd51b0cee9042c38a82 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13060 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-ros2dds_0.11.0-rc.2_arm64.deb Size: 2583516 MD5sum: c1b64e8c73f0f8e5f9c91d428b8725d7 SHA1: 52b91e9c2441baac8030fa30d5d950c343aff08f SHA256: 70598b80cf41d4d6ac4173f96c1a37d9c1209d67e22138bd932d7cb35bac2bac SHA512: 50a09ab3e771b59283a71bd1100a91c8f7add176983ce9714952e1b50950c73170870d61eff45e7afa476bee50e65e0f06f90e0935968555a5665397233e0942 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10362 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-ros2dds_0.11.0-rc.2_armel.deb Size: 2373620 MD5sum: 18c2d6cd06088ff9f2eb7316e115eff6 SHA1: 25db2077f59d38ffab0c8ecdbb70ef32bae8ff9a SHA256: 8cf9bf7ddb9be8d9986fbb762b92bdf5e07e32850c0c11aeaba471495c96e4e2 SHA512: 15b9174d4a8dcd91e40fafcfe46990f12498c6d08cab225af5545dc7952a21615f1e0a0343e593ce665c3ea911e60676c2d9dcdc8b4d00f02665792b9163563c Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10022 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-ros2dds_0.11.0-rc.2_armhf.deb Size: 2383296 MD5sum: c7aa40db382d29250f1085897d55de2d SHA1: a485ea54ce4e3af217673cd244c161c9392a0aff SHA256: 08462fb904256518144c3e9cc3185dd33f79579d1d33bd704f8c38b58be44ccd SHA512: 502e27b8f23796b07d1ad4241e054fa41f56558057f61f3c26770dea6f9ba0fc1e102b5d62dd0ac18ceeb86ee4f021a0872b78c4f1182f635db4c4cf1742b6c3 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13196 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-storage-manager_0.11.0-rc.2_amd64.deb Size: 2404676 MD5sum: c53c7128da6233e8c3df15c133e087f9 SHA1: 6b9685216e8fbc600d3a18b29ec30572afceb5e7 SHA256: c42e2493da73f3117bacc9ff236b2358679315945474ccf71de24020254d69d3 SHA512: 49f5a64bc951d2b7effc9b5445d65ff4f85b1176aa1f4d04fb75beea171beb28379732938259db7cc34a7bc472c0ebf1e1dba05b6c9adabd0ffb2337629b46e3 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11524 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-storage-manager_0.11.0-rc.2_arm64.deb Size: 2161304 MD5sum: 005a40f0fe4fa50c586381b54e8b9095 SHA1: cd341e6216c23131592daa8c5dde840d4d2b4e91 SHA256: 3d2e7269441c361981f23447ab66ad321f0658ee337e25c5d2ce5ee3afc45d74 SHA512: 38ab965c4d1fe52511bb17383249d61beb467e2de8dfea4d4e89168d68679f0db6e91a6a6ba1a64e7035faa81ae0af23c508b54ab99c1dc349235c02d32f1f04 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8952 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-storage-manager_0.11.0-rc.2_armel.deb Size: 1976976 MD5sum: c36512fed131c71b6ef8854ed35dad09 SHA1: caa00f026d217dfb77ae9ff08110f13087f76bc4 SHA256: d5b11f8c12961fba12437eb70ab0034ea63db98fe3cb2198842413b4ec45adc7 SHA512: 61f631c511271639ec394f7e568f8032e79cd56efa40c0f51d8133f77cb20b5b440c5e7ae3bb2a78b41a5783d7339a010eba6bde74b4f1bbb9052fc5852142f4 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8869 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-storage-manager_0.11.0-rc.2_armhf.deb Size: 1965348 MD5sum: d433db466ed6bcdbbd2575f6f09afe7f SHA1: 5f500817f2ae243ca76654260addd288ee0c3414 SHA256: 2f2dc6d7ffad1039ed2c56cac62a21ec4f12e5296285b3985b7f6c7973ad46bb SHA512: 42fd801ef8b1a32c21a63021d4b0122ee9170dc6839ca967b5a74d0f4eb9cbeab065cfefa93bf0add0f077670b232d72d45cc340566ac55f4b9952cb5aceb713 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-webserver Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16114 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-webserver_0.11.0-rc.2_amd64.deb Size: 2934592 MD5sum: ebaf364bda491a56208d17af95e9357a SHA1: 35d0cd8a68e9981b027a95eb7d8028968f8a895e SHA256: 2546335ab74366a975d78ae2ab2c4d9e33564db105398475e2da39065d0469b0 SHA512: d4e872fef702016582ca5b53049aec3f63e9da17f032ba35677c5699f7d61951df9015b04cc27e2501c02a0409bd6f42b31ae58e786bd535dec079a19799fd72 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14736 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-webserver_0.11.0-rc.2_arm64.deb Size: 2695260 MD5sum: 19ff1e07ffab94d4b17017d56b75a3ba SHA1: a54847e20b62d6ff71b7fa661b0d7e949ed9c9b0 SHA256: 80a6e5ff2197ea51d9416d3bf52a2587e79683540b0446adb49c46705a330ad5 SHA512: 05fb0af6aca6de3cbc996222795257cf0c5bd0bbd76b7afaa6d8827da8f79c79a07980e11dc46503e3470caef562c5dfadf06c537edf8013127bb5247f19d276 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11599 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-webserver_0.11.0-rc.2_armel.deb Size: 2406964 MD5sum: 6358fd8a8a0430104037a8fc13ab5a12 SHA1: df335e7d2da34241c7fb2e2962545baf06fa8b35 SHA256: 90a37e5067d93c40914998394c776bd8150fdc8189130288edd23ccb21b99ed0 SHA512: d35fe2c2b875d55894157d11c42bb63ee867d86ec2d28a261734aba1d5575aa0608b7b69b8d04b01074e3c27041a19b2dbeee7a4d87754adc3820977cf54ef0c Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11471 Depends: zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh-plugin-webserver_0.11.0-rc.2_armhf.deb Size: 2384628 MD5sum: 57379e470156aa02ac9186447038c159 SHA1: 6626077b60046b1a840487876e9a06eba2b04cbd SHA256: d89a2a8db504d926cadfca3c68cb7142fddaece5d6ae2e63f52382d4f9739fcb SHA512: 81a08ba1ec15ca3d9b1a067670c4be710213df3832540c5d0e507ca2904173460140bb04c064c5d56ce9635b3a0ada8c0059e472eb67771ca54ca85cb899a609 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2), zenoh-plugin-rest (=0.11.0-rc.2), zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh_0.11.0-rc.2_amd64.deb Size: 17260 MD5sum: 849a77c4efc8bbc821a0a40976d1734e SHA1: d62d558a122ec4bfa7ec126de85664c2cf6a0e69 SHA256: eeeccfb3fea111d6ff855d2aecae788279c6a319f69980da5cd8cb5524d06667 SHA512: 256cde3a2f2093ac04801e3143f2f2f2979635ccc8a2a54916a6306253180aa913f9a32a01932d318a0d851faea26a653d99c452b02f9e3b7523c191d4283a33 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2), zenohd (=0.11.0-rc.2), zenoh-plugin-rest (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh_0.11.0-rc.2_arm64.deb Size: 17260 MD5sum: fdadbafb83543e3b973de04df152802b SHA1: 7f27b4bcbbe7834754b0cec396acc78dc5be1aed SHA256: 573d91728dde92b01cd993f9f723f99a271821398e68cb3ed8fc50a4d5da54d6 SHA512: b510b71f26a40733171cd8cdf845dc50e91ddd5424058bbe4b87fe88ce27d8d946edb292993fa49e54e914c9536270e23123c6ae1ee51a15cf014e002d25f6a4 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=0.11.0-rc.2), zenoh-plugin-storage-manager (=0.11.0-rc.2), zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh_0.11.0-rc.2_armel.deb Size: 17256 MD5sum: 5ec443cd22754303bcf7a0b527192641 SHA1: a6e8f2bd1bc8d001d487a0c6a6f82a0b7d7bc9fd SHA256: 21fa55043445b0b53cfff4fb91cc9cac526d9cb0802d7d4424068b36c8174ab4 SHA512: 64c448fe7d9b40335bce143b8065c1da6dd8b8901eb4eb533547e0617d62b2f6fcfbdf9df5405352ee95b2046304efa5b1083ba7de421ead130d6c82fc4d14e7 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.2), zenoh-plugin-rest (=0.11.0-rc.2), zenohd (=0.11.0-rc.2) Filename: ./0.11.0-rc.2/zenoh_0.11.0-rc.2_armhf.deb Size: 17260 MD5sum: 8bc47cea751afacdd1ed30b9bb77290d SHA1: 1e59bf4f61872ee800ceae3ed7b6c35a951a5cf9 SHA256: 8ec6be68920dffa0b30530d9f022e2a1ee59073a110dfc0d1c33aa5a131927d0 SHA512: 28b243491fa7e512e2156701f1728b174b3cf539b696096607b11194f38343c10125cb540a808d2875f31295a2991b6d96b10774ba7cdbecea7ee30bd6258b86 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: amd64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19737 Depends: libc6 (>= 2.29) Filename: ./0.11.0-rc.2/zenohd_0.11.0-rc.2_amd64.deb Size: 4679816 MD5sum: 1a0ce1adc8ed55fd3fcadf532c462ffa SHA1: 077d05b8ae3108e12e8c719e61d91a64c1834441 SHA256: 88379af741b77022d4673f6f5eb29d23b16e9bc21c5f14a2dc9049d19e88f5d0 SHA512: b17a8299982794462d1a1d91787e76fd91ca07cd0809da5262bbd0decb82a662f0dd0d728e5fc6f7129d9e87323c4194e4b22292817e618835af0eb09f412411 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: arm64 Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17084 Filename: ./0.11.0-rc.2/zenohd_0.11.0-rc.2_arm64.deb Size: 4154520 MD5sum: 5c48c516cb1f0a1a497a124551f5889d SHA1: 24d6c8f6f3d1c316dd219067cb501168a3e17af7 SHA256: 4e0aefdb9cc5b7b5564483180ed54d2fe2adc53deafba277c246b8524b406c4d SHA512: 40e3bd3ee6ced7de4c4bcf77e1b5f7207704cee1c92b5ccfe0ea7ee64fb47e8c586a20394a4428d8aded2171e8252a9f3e5a2341005beb27072fec9f311e7ea4 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: armel Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18604 Filename: ./0.11.0-rc.2/zenohd_0.11.0-rc.2_armel.deb Size: 4559168 MD5sum: b34a2b8b8f2c5989a7d546f759307f7f SHA1: 872c43b589a99ae9d75c722a7c13d3f5f50bf75d SHA256: d32c9db5ea5ad83c5bb4acf35b2e0e51e2f05365a4f2fcc2e3332f88da9125f2 SHA512: 5eac55e4b5e0b40856a06b566060447383146b734e97796b52c222fbbd2fd984241b17f2248d05f00b6177a85ff3560ba99942636b57638a2f1ed2cae8b1548b Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: armhf Version: 0.11.0-rc.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18352 Filename: ./0.11.0-rc.2/zenohd_0.11.0-rc.2_armhf.deb Size: 4613404 MD5sum: 848b9a03b238717d12dbcff1d456b61a SHA1: 26b46ed33e29ca74c095d5a7256c1816b4977e92 SHA256: bc67d152118183bfe7f32ecbe14caeb1eb05d5e824929cf86b1d5f8a5e5beb66 SHA512: 3ba1f8d37b6f04bbde0a58cbc32fa62949cb8a8bca8d117a25db4f01e716f4856dc8d0442e05b844724123062b887d74e4aa0430630ebf2879bce81c2dda5c56 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . See other examples of Zenoh usage in [examples/](examples) . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-backend-filesystem Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21952 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-filesystem_0.11.0-rc.3_amd64.deb Size: 4689124 MD5sum: 04e5bd2e9f13a78921b259034bfaee84 SHA1: b432d01f5a7da55c290ebf16b7e432bbac05202d SHA256: ad55d0b9961ca64857c12f7e12120961766d29ba0b3a1141c05e5c064e2f5e0a SHA512: 4dda090d0473972f81af9958578cc82a6288790e681ebd96a66fb4e9a7873accf0c3d6fdaf31780a78eeb11a29c5fa316a35af5fdf208d8fe3a6ad3c4d4cf739 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19685 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-filesystem_0.11.0-rc.3_arm64.deb Size: 4206096 MD5sum: dcbdbd10cbe3b1a0f9285c8c0d83cb77 SHA1: 9d94c07d043db2cffec4944db110b291ab1be96a SHA256: 35e967d056ffadaba81aab0e983eaadca83d383dfc7c11a82eebd8054af1e725 SHA512: 04a58cad63a88af74c75030c3f7547e21dbbd30d2ab7b7e688ce304dd6fa22e6b82c1af2d37d3f2b47187f7ccbc85d2830ba4bdb411229cadf3cfc334f090b87 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16553 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-filesystem_0.11.0-rc.3_armel.deb Size: 3912920 MD5sum: 53d0ded6572db86bf7c26105c8ca99cd SHA1: 429251df132707b125e57ade65a8730a0872e6d2 SHA256: 5773246a708d8f87aab54c84195c8824273a28ea0d77d5bb83fcd3320fbca6fc SHA512: f916d0c84b572c8c7d5b6a6eceefa813dcf951b2cfc3d31999b59f1c1d2a348482f93fffc71bba63b6843b43db28a0090d54db39e1b54d67452fa26becfd4be7 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14817 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-filesystem_0.11.0-rc.3_armhf.deb Size: 4008664 MD5sum: 6ede3afce194b0daca75a2c5973c0b9f SHA1: 7578dc849b2522e42b721616c033c4d8329a1c32 SHA256: 49b6dc869c579411eccaa4c2ca94e9078bd11f539e0ebb03bcce669cb35ead64 SHA512: c151b4911a80fd776dcf6c0c7191ba8afae250b020419ee56a0fffa6add56109df1d568b06baa22016ecdc2643e51eff35210c0a52437320c7e7eb1d3de9a9ab Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-influxdb-v1 Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16489 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-influxdb-v1_0.11.0-rc.3_amd64.deb Size: 3310012 MD5sum: 0348bb53e92af9490802ab3fb00991e4 SHA1: 92de35127ce432bd325a48b7fb589e37860280e8 SHA256: ffde2cdb1a60bd8344c5bf7b1fda4868fa7ef62b1096bb506418209cb834c219 SHA512: 0462ab5e1492efba8c61632c770fa8e733056bf5a6de17eb73d3e24ff9de8c0c52cca85ab5d0ddae5bb3cbb4354b1d4ce140d057d51b48db6960987f2de09d23 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14965 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-influxdb-v1_0.11.0-rc.3_arm64.deb Size: 2992376 MD5sum: 52caee36920b9d8272e4d76b5e52768e SHA1: 806859b3b7d33d67c42a2555f28e8011663b133b SHA256: 447f2f653cb002bbe82343e51767af7ddd93b1aaf440b0d4affe8f9f2b7412ed SHA512: ccbfae64643c1bdcafef3b36af550572361044a578dda145027cab28843a85ce956b51b3fef52869f7af9e1c483f8c1086d86eb51ea466dc576bfbe6e7c11b6a Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12575 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-influxdb-v1_0.11.0-rc.3_armel.deb Size: 2720704 MD5sum: 0da7fabe46c9c5828c2f6ec6933cb03a SHA1: 976073102304d5f8a06caaaf87be5db95f244c72 SHA256: 17198c1bec1c5f2b9f6c8704ae486c1dbb119cf1177da909786c711baa0e3ac6 SHA512: e751ae84bbd87a918bea01b4751fab66dbe769bbca397194998630ee19eb33781740dc2e7e9419cbaf2b33bfe63e3be11c2abb694445f20eb4671aacd2da0132 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12494 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-influxdb-v1_0.11.0-rc.3_armhf.deb Size: 2717212 MD5sum: 305c9aa9ac0b0d10635a80e10b02079e SHA1: a2727cb235a77c842747120c436c52e166b5167a SHA256: 0f7502c47c302e6f74ae87f60bf4871c95866f36c3e050955220c0ed244a36f9 SHA512: 31be9d7ae3decbb08a7dd64d631131b8c8fc8d72ed103ff6a9522755c6e9971b97bcd1af2e304df5e6d31cead597a33948cfaa242a8118860e4d1c71503f2c28 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19781 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-influxdb-v2_0.11.0-rc.3_amd64.deb Size: 4112304 MD5sum: 4f4a927c1587eecf302ad4f0615e1e69 SHA1: f529c55b0a0cacc08de4c53a575c6b9270749e43 SHA256: 35e0c6ca930f8a22494c4f26613104f0ca00b848c6281f3a187827015949343a SHA512: 6e577bd96d505aa4ea76328bbbf66f22140af8b7183a8e551e2694836903ed5529016f92e9037df40740314e23f0aff0a2d7c51aa90949ef41f3dbffb6614499 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18346 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-influxdb-v2_0.11.0-rc.3_arm64.deb Size: 3791108 MD5sum: 7d2da7122b45eca3039092743bd76ab4 SHA1: 174aa808eed70f5824a7eaf29b5f4ddc1462623f SHA256: ce3612b8d20671b5420df8f35d504ef7715edca71076e2a9ac3ca8612205144b SHA512: d1902be1cf6c2dee59ddfa6e716055790ca2ea261147afdacfd5e1051a58626697c3aaf4bb37218b3e949d4292f0633b6deab2fe8b161b0931acddafe1618ea9 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15671 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-influxdb-v2_0.11.0-rc.3_armel.deb Size: 3479940 MD5sum: b41a05fec0410279c1a6213872b2194c SHA1: 86479db051b99efc9f88fffb2488189258e2aab6 SHA256: 0802e15b5fcf4c71f9a334f12c2251cef89b74c7e58862377412eee6bc37ca7f SHA512: 13ce77a14cf54e7aa15de4670abe93a50ac6afee934b67075b9c600057cab2809154ab1b7ab8cbafc6deba0de56bb55efd2c02d8bc7a608e5d90be8a07d93059 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15555 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-influxdb-v2_0.11.0-rc.3_armhf.deb Size: 3490588 MD5sum: 4a9137ad8b1d818cd0630136f58a98d8 SHA1: 7e892c52147c2a908be394f636ea8ce864382e2a SHA256: 4374fd797b470c647ddad586f5e7d6170336b60e54866e02b4da73a4c26651a0 SHA512: ab7230fc9b4e1ccf543c81209f13c5124de7117ba4590d9d86c4a5c49eb32977ff9d778da38c6d99e0b4c6093d92c3ed63e8280840e6753e2c3946ee3bb94633 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-rocksdb Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21708 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-rocksdb_0.11.0-rc.3_amd64.deb Size: 4652496 MD5sum: 9eb9106e1397cb92bd5093b7cc4880e4 SHA1: a60bcce2ccd805556b486a2f7cdcc307332bbcf0 SHA256: 210651ab54e71ab65bd17b04bfc7ecf2bf5c3838c043e4a0f9aed8f85b7f5c3d SHA512: b31c02a0e4a5aa918bc1b14536e9e0901b66277a1aabff5cfc18b217781bf64d6a049db51c1a111341fcd643df0724c0e2ae584b22f11112e7eb4cb77ffc505f Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19326 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-rocksdb_0.11.0-rc.3_arm64.deb Size: 4151700 MD5sum: 3602dd27c60f8bbca262a79749b69569 SHA1: 8ba66aac11388b1a8b4118df93ac92d4cd67f693 SHA256: 89215e8929509cc68453d05e90c3ddc091c478543263faa0ae80162d5b352613 SHA512: b19fe3dc896e71df98134bac404785757b57170d45bf5e663d25dcbd61e278ca663d570013200b453f803168dd67578da92473d4c8ba1da5662e07fe118c708b Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16345 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-rocksdb_0.11.0-rc.3_armel.deb Size: 3872388 MD5sum: 64d631ba4e8ae83ee58f39a5a7e8e045 SHA1: 18beed23bf14cf543a4144f053a22f7b0d12099c SHA256: 5030eabdbb315fbf1808f4a5fa73bd23fc6475038b2de23fbded72c7bc49d60f SHA512: 9d78409cdb052cfcf1ca6a80c86c95fdcec2d9245a1ea8328584b7f51037d91c1f710c9426b85b1f428b13293ef23c4bf67286542b51fe53ac70097fd6c89f25 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14568 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-rocksdb_0.11.0-rc.3_armhf.deb Size: 3973000 MD5sum: 3ea4b49bc82d1423569ba0094c5c48b2 SHA1: 9b292b87a495f9c935fc20703d92477d427357c5 SHA256: 6376e3d9e900b743955e360533432ca7d91e98cd378c3509d759667a20cc4d47 SHA512: e8792aad72eb288f45fd0070c4610d76398737e1ade9a08b9fdc84a4abb8de19c6e3c5d02cbd62e7aabc00f848dbba35dc75578f32eebb3ec70dd8e9cb1c01ac Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-s3 Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26500 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-s3_0.11.0-rc.3_amd64.deb Size: 5251884 MD5sum: d12410a56baecb04740fcf465ac3d99b SHA1: 84263e365020712b8913eb4d09b744d263ded2f1 SHA256: 1753fb270faea7e0221e0bd7ea28cc5f2bc081633a336e17a24cf074a56d6a0c SHA512: a65e4b313ea14e4d4821c4e7957adbaa367dd29d3d6252536c0bbb9c7fb09432b38a366d237c7f8f43cbddf8b0eb301c70e2973a3d99ed2e24b2e224ad7d997e Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25101 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-s3_0.11.0-rc.3_arm64.deb Size: 4907832 MD5sum: be72f33f2e056d57b1a31c8febae49ed SHA1: c3c9a0f3fa853372678dc28ac97ae23b4e1c8d35 SHA256: 0069c4f8751b3a3fc62fdaf1613dd628a62d165021509ea833535325e24cf873 SHA512: c79fca2a986f55d92603e82d6cd1b944d194f144095778db686aa18552923ed144235be12792f042a663c64cbd1490d689d2a4661960bda7356f12099bf849f9 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 23436 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-s3_0.11.0-rc.3_armel.deb Size: 4758064 MD5sum: 6df051414ea90eedf0b7bdbbe9adf34e SHA1: 4041273a7168ed486e02eb72a61956748b77e891 SHA256: 431c78119518e7fd23228f505abdd95ea692b7da88b4bbb7b43e33273bb9b82f SHA512: dd6ad9d4e34b9ad1810c74f4319d9aab8b11a1067e22bed1077bcbfa63a7321b47d22c99b19f228e94ed09e0c718f0e8b57739976593e912a93b5b99498466c2 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 23303 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-backend-s3_0.11.0-rc.3_armhf.deb Size: 4797804 MD5sum: 436afef09cd99d3b0eda0b2a20848525 SHA1: 643ce1164c0442a795e0b8a31a31033ec9221121 SHA256: 4efc16fee8907f61be7fe2b156f34e64cebc675ae3dcce44a16f0b931948bd2f SHA512: b787e9f99f6709a676e5b897e5b61cee0417dee0831af97a101f9483f623ba16b1f5149730428dbf32afdb69ba9865a2b8fe1e8e28c9c2d6a56585feda4fe6b8 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-bridge-dds Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21765 Depends: libc6 (>= 2.29) Filename: ./0.11.0-rc.3/zenoh-bridge-dds_0.11.0-rc.3_amd64.deb Size: 5348592 MD5sum: 208fb4b1550bf9592647fb1616b508c6 SHA1: 673efbb4f8dfa184a9f65a815b1f1cbae41bf7f4 SHA256: 367237535920c9909a095597ea889f8d86696cd4713c86deb3320e3f81c03ab3 SHA512: b31ed252e1a2fc31c413f15641afdcdd65e01c9aa284352dac8d06efcf49c5c669db6d51865b21b54e81087b3d6a9a07630bd370464c68d0cfaeab7348741570 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19340 Filename: ./0.11.0-rc.3/zenoh-bridge-dds_0.11.0-rc.3_arm64.deb Size: 4794552 MD5sum: 0318b8c4774a3922b46f531373d12247 SHA1: 98562477a9d514b41a9f10d541146305a3c90066 SHA256: 770ffc9bbf148165681b289810d30666a1707c0236ec4f47962b522c8c2549a4 SHA512: 8c5fc575417c7c95823f0d76d03afe7ab3fab787f6b03730a55be0e5e5afffaee0e2d351621070966265f0dd06c68bd1914614281eb15d2195f251d49f4add49 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20526 Filename: ./0.11.0-rc.3/zenoh-bridge-dds_0.11.0-rc.3_armel.deb Size: 5118312 MD5sum: bf3cdfeb102cab49a05c194ee7da79d2 SHA1: 8dceabcbe4b6c25412cf6b9d8c806efefb1ec1e1 SHA256: 4282235b3f94f48cfe30a07d8d7896532b030cd2b8c2afa9c44be01df16c885b SHA512: 4ff6137deecb5b13190f4f1b2081d7901425542b53bf19ba50f081cdd6609ea4a9881b3a0a843dc35c77e1212f8cf24672f91b3fc04e46b9cd86ce17b6efe2c4 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20030 Filename: ./0.11.0-rc.3/zenoh-bridge-dds_0.11.0-rc.3_armhf.deb Size: 5161724 MD5sum: 01e3f556dfda2108ccd01da5fda50090 SHA1: 8c33a56d83a2a8ff746d386d2fdd9e667cebd8a8 SHA256: 7d2e2658dae20570b91d2b9123962b12b06e2d639f9a71f7fc15d40825ed17fe SHA512: abb7ec83d7c33dadf770cb0ee7b88fd1267c838b858733b94b5419332585984790b34abcb2306965d21c514ed81f71b5ebf22c119e7124c9fb34ba4e7a970218 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-mqtt Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21352 Depends: libc6 (>= 2.29) Filename: ./0.11.0-rc.3/zenoh-bridge-mqtt_0.11.0-rc.3_amd64.deb Size: 5059176 MD5sum: cee029a284c1c0605d82a7f9a64c7155 SHA1: 2650157d6dbe7230d992fc01c161421326f48024 SHA256: eb04ac0dffef38de013882e0877c4872c286a598d51cf7e37002957026b37edd SHA512: b8e2e4fb32ae4f7597a5f6bb65e81d05224a446b44b50499bd2e644333a5b1f9f83a366f0fddbd2c4bbc48effbb02c19d34b224f8bf890b6c0793552c62ab901 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18878 Filename: ./0.11.0-rc.3/zenoh-bridge-mqtt_0.11.0-rc.3_arm64.deb Size: 4523004 MD5sum: 6104640d270f6efb50b53dadffb870c6 SHA1: 0f0d3b2b65b771036bec54cda488cdb67453cf35 SHA256: 0769a847253d3ce2c3b789616ddbb59c248f24bd1a69695401bd25f4421c7e30 SHA512: c1b1025e4a7bdc7aa04c43fa43e6e160e6d5ae04ff6c6f25e9e0ca3e0ac392b792e622e10d45dcec047a39a7706175598b903908a37d2893ead10630cfcb0b64 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20230 Filename: ./0.11.0-rc.3/zenoh-bridge-mqtt_0.11.0-rc.3_armel.deb Size: 4857472 MD5sum: cb1172d4214f068918a466fc03526c42 SHA1: 7f266bb25fa27920480aa1bab0b6dcd29bf74945 SHA256: 5da050a7ee531c2e2e802964fbf4e8e4e2c56c13a454bb47d2955086db786f31 SHA512: a7297952c5123c6c4a88080ba6bada72fa70a0b58deef1dea0817e3d9c622713b78094bb1d24bbc33ad184f3cdff7df7417b6a359de7816866c12a4e0601c37c Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19967 Filename: ./0.11.0-rc.3/zenoh-bridge-mqtt_0.11.0-rc.3_armhf.deb Size: 4890192 MD5sum: 51e9e52873ee3cf922a0b5008dc91d41 SHA1: 0de3e95b2352aaf5e992b8f0f8a52f56d70a83c8 SHA256: 44449f5770077b5c8f5ae99982e1b1e4f221762311662ff2ff55dc3c3292929d SHA512: 5eabaf3e16161bc338fcf1f86384521020cc162f62b6355d3300dfb0117ad190f70b8d8221f282dcf9a50d4dca6e7a0b8688ce93f514680755537b97e073b377 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-ros1 Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 22832 Depends: libc6 (>= 2.29) Filename: ./0.11.0-rc.3/zenoh-bridge-ros1_0.11.0-rc.3_amd64.deb Size: 5450560 MD5sum: a592f019b003d973d9369be12c8a30e9 SHA1: 040ffac51b066a8c087ff984576d48f805a8df4b SHA256: ae2dee56f41ad0ba146472c6b71bb4d69f3efad2519ec868978c01fbedbf06ab SHA512: e9cf6270111a0d9baa0687df5453cf96090e7fe19a34f4cc0feabc277c7f9aac6d4aa0c98cb43c07da73d6d7e8085e922a191dc742e034ef6288a3db9280c2e8 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20274 Filename: ./0.11.0-rc.3/zenoh-bridge-ros1_0.11.0-rc.3_arm64.deb Size: 4880320 MD5sum: 15574bb24d3396e178bb04fd3f838a41 SHA1: 96c774c8f53710ece24889f463c5b628b8dec40c SHA256: 944563e09fc83e04d049565de6cf804b7ccee074d31a3eeedf3867bfe65c3b77 SHA512: 156ad938ba8fdc783f1689ae6154face6f7cf12d920faf7b1d1034a8fe79d014f798c2db37bbad46895f6ff4990ea61f3cf6b5964faead0f9048166ae12c5cab Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21627 Filename: ./0.11.0-rc.3/zenoh-bridge-ros1_0.11.0-rc.3_armel.deb Size: 5250152 MD5sum: 5bafdbce3499b47bae4e36b58a24aed3 SHA1: 06c61352da1e76edb1ed4d26098a6a86cce59714 SHA256: 294d2e271706881c1fd9e61a4e3ccf99e75c890198b81966c828eb3bff076efd SHA512: e1b05147a6967db6e9293993f2ade591f5dc77f307013fb266bcb5bf4b7c7d7f145071be43e8f68b955d1581a116b35b5f3e269ba96a9e55ea38cfe9fdaaafec Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21313 Filename: ./0.11.0-rc.3/zenoh-bridge-ros1_0.11.0-rc.3_armhf.deb Size: 5275448 MD5sum: fe22f0401fde53c79f057ccf55d823f7 SHA1: 2003589f2e5d80cb240e7eac9210777b64db5b71 SHA256: 4ab4143478d4acb68d03a5b25157f55af544ddfbaf7e27c30fec35ba015db537 SHA512: d22632105cf7b0425cccd5f215bdfb7153a4937851b4c0473f199b84d5cf66ce5c533c14c84aeb190225c21f21f53ff6649111744ae4943c9ec3db5d2756ac20 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 22355 Depends: libc6 (>= 2.29) Filename: ./0.11.0-rc.3/zenoh-bridge-ros2dds_0.11.0-rc.3_amd64.deb Size: 5469264 MD5sum: fe9dc110fe78b312cc89c1166859631e SHA1: 87d44d637e49c5b0d8686d7e5c6b283755b501db SHA256: 0dbb557308ba4fa91224018892dd06218b2d8a425f6984bea00666371bbd72d7 SHA512: 9169a7f2d7bf6aac513c3dacaa969cd6679c2cf91edb7296afe841c3666eef36ca3776efba060de69cdbb9a0d182d94cef5a1cfc9871c604dbd5c2e57537606e Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19919 Filename: ./0.11.0-rc.3/zenoh-bridge-ros2dds_0.11.0-rc.3_arm64.deb Size: 4913864 MD5sum: 1d68c7461536bd90a1e1469a3c8c9b39 SHA1: 24c3a697402c6db35f083edbf450ccfe54bd7885 SHA256: f22c62218aa19934037de3f5be95da7970016da3fc8b9cf3e45b2ee5d6637845 SHA512: da081bccf9b9595deaa40e41d91c615cd5ab9bc012955e2ec1b0b405e8c66fa66e91398203647172a8a5a04a14cabbe9b079a479631496d10dbef60b014c136f Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21126 Filename: ./0.11.0-rc.3/zenoh-bridge-ros2dds_0.11.0-rc.3_armel.deb Size: 5239284 MD5sum: e2e9ee3c15848c83fb02837033deec33 SHA1: 2c5e0ac1e93f0e8298dfe70c82dcb4a183b95ae3 SHA256: 0bdc90de67373913715b99a5d31aaffdfe6dd010518a58610d269dee5c80dc80 SHA512: 27c2a2d08f8d551ff73ca21d2729f58c2f09307119f6df21e34e5c27cea82fc36239f493792261a3fd2895fb30c1cb05fa401d2f3ab8759c98b05bde53c531c1 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20622 Filename: ./0.11.0-rc.3/zenoh-bridge-ros2dds_0.11.0-rc.3_armhf.deb Size: 5294716 MD5sum: 512b4d3d2ccfbcc5d117d5338f6061ed SHA1: 2987cec070cb54f67f1f7ba07c0e83d4423ab2e1 SHA256: 11734e4eda5477062b811337dc4a123c856e743f9ae9fb8f88deea6419eee331 SHA512: afdc30da1328418f80381f47a3848a0f4d56cb75f3b5c0012a35b2acce5cb526c9ca1d5aa322897102ece6fa4d4852004a8034325003b67f0d6a350017d1ae26 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-dds Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14133 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-dds_0.11.0-rc.3_amd64.deb Size: 2741708 MD5sum: b7a8aa29018380dbd9ab1b4f952ec020 SHA1: 00ad27b889b3903adcecfbfcf4e44d0f656c4eba SHA256: a7e9b6cf8a0e705ae320f6562cc3490b2670ed6f154561730ac25bd496fd5a0c SHA512: e64b7ad5954072f3648022471a6b4b19e9ec5492a87214d5dbba4b17a17a46067cd44d70199958568a972dba1668bf45230ccc424002e33c17cee1858a51f60c Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12486 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-dds_0.11.0-rc.3_arm64.deb Size: 2470004 MD5sum: 857d26f592c4a01272a6e633ce6e5f44 SHA1: c096de348d41ce9a64ade79ecb3ead23cf15ca63 SHA256: 83c652cba7693efa90f5ad8b496e3ef4a5ae0829edfab2e2f3443b697a4b9040 SHA512: 37a9369262d04f00b1c6f5990d0691e643ee9faa8a22dbd438fba52b4c8dcd6d46293074f8c5d6f41fb424969ac970ac174f0e580dff6fd6da4ad1e174b170dd Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9772 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-dds_0.11.0-rc.3_armel.deb Size: 2253240 MD5sum: 19ad88e39386ddb1e8f670b8790026a4 SHA1: ba81963aca9b98451d5f2fbd0730dce5a43ca062 SHA256: 00cd3e7f276f6b0e7ba8730dbae3a9e6af9891738d4fbc2eab8d78e4be8fb0a3 SHA512: b8306b8db93b2d4d114f2aa8ee1168a210e9cf034e5a66f93a5064d28eb38828521dbf008504bbf65b7d59f8e799d385d4f4a0bf9c9946163fd8e44f3d9bf4de Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9448 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-dds_0.11.0-rc.3_armhf.deb Size: 2255932 MD5sum: 0d1d1987eafe2dfe611c6fb432912703 SHA1: ba2a0c7e4737fd1444b0d2d31371396d9d18cbc9 SHA256: 2a81fd4ccd90d4c4eccaa1a0e238d5797a98b704e3f38edd59bb56f8256efd7f SHA512: 819b79627d13d685f18e667de8ef4b16c6dca5b96fb9723506aa26d039065b36396ebf75206e6c058f52c832d16e3b9cb9d04c8f449dfce934e8afbe5d8ff008 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-mqtt Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14775 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-mqtt_0.11.0-rc.3_amd64.deb Size: 2940304 MD5sum: 5e5c5ef1ff30eacb8f12cb4a92d93672 SHA1: fc5bfa43355e1db9772641a1af3c80169dcd161b SHA256: 6a846142adb4814331b2def2570effa775b4f76231384104cce88970983a66d5 SHA512: 9e90a0865c0253afb285b9c97e6ccd374e3aa0bb2fb0fa64668be18e22c2ef2a220616ccca96239b22cd41af4af550e95fa26bcc503a21d0425ed147e30ea091 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13021 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-mqtt_0.11.0-rc.3_arm64.deb Size: 2619780 MD5sum: 108e97189153131d6b008288c3b99078 SHA1: fa266dc590dc1f23b25aeced8877fc6c53c349f1 SHA256: eeae3fce176b8c49bd24fc24692ea0a92c0bd3e23d7677f859de1df33cd8ac23 SHA512: a60205d7f6a175c81f031fe50ee739652e5f05622d9a952c89b57af2f1e29a894801e316fab91f683111d8b4b4bbf36b45792628e0dc7622ef47fdafdbff8aa0 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11168 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-mqtt_0.11.0-rc.3_armel.deb Size: 2429096 MD5sum: e3add8511bb209173f17d72ab70fc04e SHA1: 7a0326d9b9dbab3122ab3d558699f34435bacd0f SHA256: b72ed927f296b1b020e5342578184c4fc613cfa975ed48a705ca1f4132d8fd69 SHA512: 76a47ad5e62779856bff3e9df7da38fde625ec4ef6cda00e19393e2d4555116fbc9934d8702167ca103ad26b57ade7702cbb7901f5728958bf932ba17c640d61 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11078 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-mqtt_0.11.0-rc.3_armhf.deb Size: 2432876 MD5sum: 2db8ceffc5edbe9c38ef2b79c1321e34 SHA1: aa72b9513858693533fbfaf9fb5d316baab9e901 SHA256: ed128e6d897f3bdd44dbd81637b91ab7cc0c05b9723e104393de1ebc2b632180 SHA512: f923b152966289667c114009c757bd434b6ee9f3c1fbcb3ceb8d60697963e65a8824fe1d15bd2fd88615922b7a39930a338d0d585bc2c3ea5dc6a959b8156a13 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-rest Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12975 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-rest_0.11.0-rc.3_amd64.deb Size: 2383328 MD5sum: 17044ca346005337dd5ab52a86bbd6d8 SHA1: 7be6abd4f555499e6e910b41890f8c5cc8a6c639 SHA256: fc0d97fd0a1a45be377878c2a4ad9728a93dd5f41a7f74e6bc0007cf50302aa7 SHA512: 3a72f96ae218969d809208720b6358f4bd71144aa3daab27eefb87d4d59f36598e835c962459fd03b30e13f4537fb3a373caacaa38127569ddf4ca8f791c6b18 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11321 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-rest_0.11.0-rc.3_arm64.deb Size: 2136568 MD5sum: 3f2f8d815daa6fd758daf64a0e0dbbbb SHA1: 5e9fcd58c9da87d973cb886da5b296f008d60a01 SHA256: 411b3a774edc2597e22f7042cfcd81e1bc793c61c5fa316c452fc0704ac5a1cb SHA512: 087432c0f42824374821b0582a4a44ee71994d78bb21cfec2146e39725a08fa235c4f26cd0d3f834aef55bc45a9d56bbde50f692cbcfe20450722906ad3809e8 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8703 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-rest_0.11.0-rc.3_armel.deb Size: 1931932 MD5sum: e78fada3fe54929830bf6c434576c2b3 SHA1: a9f1e9a75abc77ddc8a81064b1157e1312b38965 SHA256: 6f74ed00d61144cd077d8d46e510d5bb820dc77e865895bdf5f6af663f53db48 SHA512: bd8c6ee25c9fe40d4ffcbf359ab8b343c33fba3f51640af58b10ac06f9056d9a74ed2c16f076c3e8c3caaa4dfe4de2ecc27d3d09a9ef79c9213711491956c163 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8628 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-rest_0.11.0-rc.3_armhf.deb Size: 1920168 MD5sum: 773bc1a8dd073d3ee18d31116edf60e3 SHA1: 87f02dd9bd09d549c6a1d6d5953d7a06e974485c SHA256: 2447423266a1bc12ceb01f04f04b56d718b3c3f99e63175b3dc7a6d42f3a0ebb SHA512: 5a59d1eb625b89636eb92c3852a8f6db47437b6b633915dc39930dfc8fc9e6db09c535a73da0447a950fe2d759ddea840c0cef79a66f227a32d20346fe7bf337 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-ros1 Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16755 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-ros1_0.11.0-rc.3_amd64.deb Size: 3361676 MD5sum: 39c9781f1c9f742955b49271850cfc8e SHA1: c2ff522c7f9c9ab8d2689bc1922ad5222f7ba918 SHA256: 2c23b71c9496856d2967d4f259eea72909f80ee53c23ed49c7e8b01ddfe4d23f SHA512: 4fecc1ba87c5f9f4da760bea46d10aa09dd9deef7737f807e8d7a863109b0ed2f90bf4a39724592ea11d588b801a12dba48715eb55f920da05f1f8b71e68df76 Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14930 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-ros1_0.11.0-rc.3_arm64.deb Size: 3067920 MD5sum: 9e9d8c59c046db6352bb984eaf6162bf SHA1: a46ec2c8e080f78ff5734f2d4cd392c7928a7aeb SHA256: f3d63aa06db803b81f0df79bc3582a8e475854ea3453041596b32ef7e9c051a9 SHA512: fe9cba6418052ed6c016b3a2195a779f9fac71a117b2c1c69901fee0c10afbfa2d1b77288608b7fbdd60e6d6fb33e0f4451019151f9d2a0c5eb0f58376a5f8b3 Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12381 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-ros1_0.11.0-rc.3_armel.deb Size: 2896400 MD5sum: b940ee3954f8145f5fb63ba4ec684ec8 SHA1: 8c85db8d1fbbe11df364e3c9e73abc8cc4eae534 SHA256: 12410b37f7bc98ec109f5ff29ae51043d347b3e80d99903ed36b9fe4c1c54da0 SHA512: d19b4b049b5d59e2127bfa2ed928e7f8b3955cad52129c5ae7166a99b328a4c19f3dd3c93ca6dbeaad639478e1a07d47383a818351eced7e7423cc6fddab0592 Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12206 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-ros1_0.11.0-rc.3_armhf.deb Size: 2871700 MD5sum: cf4b96824913e964d808a59463ad35ab SHA1: 2768f2273e65515909e356b3e304d4db142789d8 SHA256: bfff6c96e00ff2255ac33b997bcce9eb3d2b748fe9b2078a2b35ec858f93a1ae SHA512: f37efc113388479093cd3c32d8a71786df86114a7e84d78c86a05ec939fe313692b4a3a239bd23bda53d0c94ca03ccadc5e0d72915aa13bce1082379a159d928 Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14778 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-ros2dds_0.11.0-rc.3_amd64.deb Size: 2861092 MD5sum: d77777f6d1e8f4c44e533d63421e2442 SHA1: 74c1ff2728657314b1bacdf8ff1f49010e68d2ee SHA256: c30d7c03a362462d88882ca7d88dd87599f44e90ac4dba1bc4936c1c3c280525 SHA512: c2099a1480e378ee1cc7e78c2fe8815c227142a64b8d151a1a439da6f76ba9e166b1751dd8f6d9f186f5605b9ee4531aacfd74f55ac54010b3223102ca659e82 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13076 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-ros2dds_0.11.0-rc.3_arm64.deb Size: 2585064 MD5sum: d1f0acc6bc42444dace791e07f1145b1 SHA1: e427de991fed2d77fa0b9c3e269a4b81804e5344 SHA256: 07669e86fd5d6138ddf5eb7f12954d1e7b2aa6ce3822c9eec1ba0eb592a4725a SHA512: 4ebed9d7ce391478d40688b63ee49aaa96db9ed89b3dd7fbf2f5076418eea9cf8be890021421c9c28751964a0cbcb15b68632895b62755b90345af08f821ce9c Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10362 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-ros2dds_0.11.0-rc.3_armel.deb Size: 2374476 MD5sum: 78cf7691ed1294625256aa9158a14ec7 SHA1: 8e81e731ee76b4d0e4cfc7bccc4b97936887c877 SHA256: e0eda24913b3612a4c6fb87c65ddb009d4d121aa894a4419aacfa12853322791 SHA512: e488745f2a969dfc55bf207d194c83aa26943275b4efb20cb7e08dcbeb397e5b8468fbdd67ac14b3e4de7e32b8c3b4eecc0a7e172f97180e6b23f5e2b40426e0 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10027 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-ros2dds_0.11.0-rc.3_armhf.deb Size: 2384872 MD5sum: 548b6009355581d1cd27150e6250401a SHA1: 93b0eadf906f4cb8b9f3f55759ed594ed8217be4 SHA256: afeae801e9bf77757774311c7847e44d489688842da2cd61435593caa4c66ebc SHA512: 16330011171f2f54d7452f60b1058a3d6fd520330537675c395c3e57b60551ff509ed243e9dda2fd57c97396bd6cc1c5876d3889fea07f617fa1a766e3e7a145 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13196 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-storage-manager_0.11.0-rc.3_amd64.deb Size: 2405320 MD5sum: 43d834d90f1ce46f1e1489d138880fa1 SHA1: 1109fe57f277260341c8749a8ed2c2f869d70d20 SHA256: 1c96c5a9ec0b2dfd93b00c9e526e52eeb5fdc75616b75589661ea7a4c540e884 SHA512: 7cff426f6ba178c5d6aac384d92ecce51be697762b29ccc52decab9f29e6fc4a6b233b8ac18f595d9b4971c04fe8629b512f59e78c72918290383a5c6245d893 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11512 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-storage-manager_0.11.0-rc.3_arm64.deb Size: 2161700 MD5sum: 9cb8caa933b9ff10a53f70a7f4e82c36 SHA1: 130e26867b9b85dde35ee68efa7eb084785eb180 SHA256: 9320515a8a9db050af77b81077209e9bf409ada0578e25de726bf71986ac947d SHA512: 4c941927316e258f124e46badfb327e7c9f62dcfdeb76b49fcbd875941af3c29f3830426d5288c685dbbb74adf32679f5092ec4031f69a2818f4d6dd379397fc Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8951 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-storage-manager_0.11.0-rc.3_armel.deb Size: 1976804 MD5sum: 50840ae0d211b4f52b7ab0ace60af528 SHA1: c16e3398b2458c02354deacef78cbeeb3fba3400 SHA256: 8222614cd363e1f9fc6504c41a52ab32a599c75fe1cbafea6986fa03b3984863 SHA512: bca6084cd7d245365c26504a0dc6d07692e40ec0ef315fe70c9b514f0180847026b25bf20e6d3a96d01c6494e24f6ad14402cb56161a2ecbda5d074d07001024 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8869 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-storage-manager_0.11.0-rc.3_armhf.deb Size: 1965444 MD5sum: 60c39ff711b512805ecc3ad2d5f719c4 SHA1: f45515ddf853f26e1cf0501854f20d26ad59161d SHA256: e352458ead306db38f960a217434a515304ed7074d376a65a43722ff8b65ffd3 SHA512: 151e480997e8eea3628dc950c451384583647dec3cabacc329b10d3fe0550c07f3070a37b064227caf952776618ffc06128c1b98d2fec94f7523867cf0d24274 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-webserver Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16099 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-webserver_0.11.0-rc.3_amd64.deb Size: 2932488 MD5sum: 5e8df4488a56fdf2e0d469e0fafbd682 SHA1: ddb65ccc90237fcdaedccf449e46bc3774b5430c SHA256: d9d3caf96a559d448daa8c3ada10abf664489bd54363fde6b42342578a5098fc SHA512: 8ac6fc2e57f4fa80e5c2c701a56260a4f393f75a6f3c55b6cae7475d4411454022767738cd80fa291181d1514789c9534eaa9c5fff223881cefdbedb80da4611 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14709 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-webserver_0.11.0-rc.3_arm64.deb Size: 2692628 MD5sum: 325fede1557ed4694bfeeb9bfe613121 SHA1: d87f8d8ac1fe776d3cd72b040cc22abddbd9bd15 SHA256: 9e3404b9e419522967ed59718c65894edf126d57cf786c9242a5cd0011d3fe79 SHA512: 56ab5c152692ef823b83ab518bf3df3b7c26644f02c88bd1d8eb46e030bc77689b106a29d826f37676479c444c03c477b0830f76ee80ca39e2cb50471ea0b7c7 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11597 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-webserver_0.11.0-rc.3_armel.deb Size: 2407972 MD5sum: 68df87f4fd34fe7449bffcff08de72f6 SHA1: 4cef6181f0b67cf61ebc7678975dc765aa1deb6b SHA256: abca2703727a3fa316286261019649c054286a466fbc40e8bc3be0579ef6c7de SHA512: d3d512a34eb8cee69d9c5ed11f9163d8ed9fc64121565852143463902d4f5d7f3d3ebf70434043d5fc647787ebf7541211813c868a88dc5fee268691c07d3525 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11494 Depends: zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh-plugin-webserver_0.11.0-rc.3_armhf.deb Size: 2391720 MD5sum: d18a941892d24ab53a6b4e5295e05c78 SHA1: 5a75bfaace08529af0cb4146e34b44ed15eecc1d SHA256: 6155028924ee3ddd188e9f7e9e208c53eb7d0d9af8de68cbbb4120286872ec1c SHA512: 0f49a204863d6905b2d61f7e82c0b3625c75cf512c28dcbfd4f68f09778908721415ddb440b3871cfe121bdd20b36d51c9b3f394fe8a69843b6b1e312fe80f33 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=0.11.0-rc.3), zenoh-plugin-storage-manager (=0.11.0-rc.3), zenohd (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh_0.11.0-rc.3_amd64.deb Size: 17512 MD5sum: 30e9debd8f594d4f708be0f2e8ea87ff SHA1: dfd96ff1af31128589639be8c6988fd03fcebee6 SHA256: e091af87fde2798e2ec84c95cc58f42446126333c1665a4d4e2d530694eb78a2 SHA512: 5f5e67ccae1c58c31dfe1ba7750d707d5412e585fb8e8abb74bed3a4505951f29029245f6981886046a1274df20f38776a3303f50b76c67dd33490c816513ab8 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=0.11.0-rc.3), zenoh-plugin-rest (=0.11.0-rc.3), zenoh-plugin-storage-manager (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh_0.11.0-rc.3_arm64.deb Size: 17496 MD5sum: b8c6eb4948284b04807c7ad57a455e34 SHA1: 8e9a0ac7a3c8f21acd5a53264a0d3acea7534d4c SHA256: dc1622bf8f3d26d6b5f0205bdff99fcbabd1c89ab5d2a97e8171485033f5e0d9 SHA512: 20aba8bc43af77cb4a083c50e70e1a99da835e35fd1062b74192f75a952b86dc1ce451653b955bfb7554eec13462ed7fb8a3dd0ef054e330ddfe491ea950f4f8 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=0.11.0-rc.3), zenohd (=0.11.0-rc.3), zenoh-plugin-rest (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh_0.11.0-rc.3_armel.deb Size: 17500 MD5sum: 39a3a996126f149acfedce1e5b4132d9 SHA1: 4b396b9d16444b3e398429a41df297e379509b44 SHA256: 9db53d1cb82de1d0211364581e80611f8b3c01df280e35896e2a3493b659cf4f SHA512: 32dcee19e2a627d341e20e547904a5b4bb34763f6fb951971c25edb4624ae87180d135da8d1d2405828db50e5fc014b79295e846d61a6c24e0256ab21d9c5723 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=0.11.0-rc.3), zenoh-plugin-storage-manager (=0.11.0-rc.3), zenoh-plugin-rest (=0.11.0-rc.3) Filename: ./0.11.0-rc.3/zenoh_0.11.0-rc.3_armhf.deb Size: 17500 MD5sum: f825bd92e5c64122eff0210a51a5be38 SHA1: 415d5e24cf789a54fb4fa1224f7a3b92d1f4c356 SHA256: fdc1569ec36ca63342ccf51fbfcc928dccd2ae9bc495079faeada643bc0fc7db SHA512: 8fad1172426efd7827a431ff054b840f5b92b12d0757936c4946546f31b1ace875e6d674e49639c73646402e23ff67152d96a7add342bdd26d17fc8c5c5ea7a9 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: amd64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19724 Depends: libc6 (>= 2.29) Filename: ./0.11.0-rc.3/zenohd_0.11.0-rc.3_amd64.deb Size: 4681588 MD5sum: 4446fedad70db3c759a97911d05c4e30 SHA1: c520a233db4186908672307e669bbb13933f8097 SHA256: d38ac62f0bab99a14eb1d0698594c49be51c8540e9034502544b0df4783646c3 SHA512: 37f7967669fd5592d0fe52860b2ef8a643f384abb3d12c89ae0a5fe95682d61458cae8a72ab71010a867b33f85e9ee9b79a48cc04a49eaace65bba068aca8ed4 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: arm64 Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17066 Filename: ./0.11.0-rc.3/zenohd_0.11.0-rc.3_arm64.deb Size: 4153940 MD5sum: 794f7140a4f5634ce851da0dc3d544c9 SHA1: 9baa97ccae609e7802b847db7397f70a88bf12ea SHA256: d656118e3ca0cda74ad61cac296c6af01d3de1c06b2df3df3842e30c05fa0e66 SHA512: 83dde5667ffc295780bf428b5fdf61944a364df9e655cc197ccc75f471c60e5583ab8c41a66271981a50c55debbfcebaf99ca7fe230e071a187a5d4d15052379 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: armel Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18589 Filename: ./0.11.0-rc.3/zenohd_0.11.0-rc.3_armel.deb Size: 4563712 MD5sum: 93d8449fc11518a8a44585a379719cbf SHA1: f31dd062e8e84aeefb4ce95fcc31a007bb1326d1 SHA256: ea91ab3ae7a5ca61d6a8a06cc721efdb8853e2003c41ad577b4ddb60655a4c48 SHA512: 6b29e6a18b620951795d889efe64c497a8f7679ebf333f012bc2aa2950d02087fd2b23262d66a9b83f7a5977622eaced60e30c7fbb53f4f921320c6df969a947 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: armhf Version: 0.11.0-rc.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18342 Filename: ./0.11.0-rc.3/zenohd_0.11.0-rc.3_armhf.deb Size: 4613464 MD5sum: 3d75cc99bf9d463fd73300886e3222aa SHA1: 8aedd65e825e7cae70b90dc773c4fddcc17a83af SHA256: cc391878aa5b5139c0da67c3837b30eca8f0f04548718288ae5850cb5976dd16 SHA512: cc778b20a939b5b9de986064fd05196e576dd00e8fa2533778fa3859d5ee0d4c270f0c278d2b1182baae32fa55be5e50a328203856e0c151004ab5516fd5fd9c Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: libzenohc-dev Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0-stable) Filename: ./0.11.0-stable/libzenohc-dev_0.11.0-stable_amd64.deb Size: 32332 MD5sum: 160f11596737d2bca224c41ef322c39d SHA1: 4a6443789a92e6860aafb03223a8bd97ac88547e SHA256: 88132e561dd49d5daf4992ea93c9ee54bf05efcb50f49ba7d5558c05c3d08269 SHA512: d43cefd1191ede96a4fd88c4c79b031404b09492edf05deaf0792b4bfdde0102ac8d487c97ed38b1a79ca755a022cb3cb513b1e1b99c0388169e848b4fee8cf7 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0-stable) Filename: ./0.11.0-stable/libzenohc-dev_0.11.0-stable_arm64.deb Size: 32316 MD5sum: 51fd8d8cb9b234664e5296fbc3a32f17 SHA1: 8f0562389bde74eda3b4ceac7864e59879124f5b SHA256: 91b0bf1261f54c7a77af92cba9d03b0d9c4bfbdd8890370d96055670fbcb7cbd SHA512: 668ceff7bc463159f1cd6dd8e8b5319fd9ede6ad9c251a1f06523301a668de0f6eccea9b0115563dccddebff6c72ca6ce97aeab607077cce1e793a076e71ab3e Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0-stable) Filename: ./0.11.0-stable/libzenohc-dev_0.11.0-stable_armel.deb Size: 32320 MD5sum: 262e9c8b2ed1527a06ceee65f62c928f SHA1: 7f41bf682bbd3de29afb2967929090117c00303a SHA256: 07019943efda609fb5dbf36347fe03c72476c34832026f1905acc9ebc10c1b03 SHA512: e52cb0c9e1684a2c584e78dbdae8bc2fc4359c231fd99bf03867ad858123abf6ba301884ff1675b5d0ac9a1b4c433f0731bc6a495d7198000b2a9f89f173d618 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0-stable) Filename: ./0.11.0-stable/libzenohc-dev_0.11.0-stable_armhf.deb Size: 32316 MD5sum: b769cac6ebd7b1dc81df26cbae45416b SHA1: 5b37cb0b24d0432293785c68abf526e0186b8ed6 SHA256: 30ed794feeb9a8f51c3fa6b2a30e8d50bdc66ab8fb2c8ce741811df7bfd42068 SHA512: d889ef69e4c5b94b598797a3eb53b134744c616b91b35c27a8d2af8fdf6293d9202a5ba039692bfd2aada2b8f4fbd45a56a2cbd1f858905945fe7e9193c83a31 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19367 Depends: libc6 (>= 2.29) Filename: ./0.11.0-stable/libzenohc_0.11.0-stable_amd64.deb Size: 4629404 MD5sum: ccee43377584c690e8d06eec029af973 SHA1: 9572d32675c03dae9fd2fd44a63de2b49ab2c043 SHA256: a732afcac7fa814b546fad376a78f414657346c7d02e4812b92279c841fa9d0a SHA512: 9e437eda8e25bb42c27b4b986aeef50560ebc714d3a143aa83e2c8c53bb785bb9b63a5143bb424262278ce82a4028daae449ff629cb0ad2083dadd06996a33e7 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16875 Filename: ./0.11.0-stable/libzenohc_0.11.0-stable_arm64.deb Size: 4101720 MD5sum: 166f5bd4e92f2b5f15216bdd81d8b759 SHA1: 3488b92b8a37498dd1f328d90d5178fb7652fbe4 SHA256: 6da20f8ec7d6150abbb736f09960ebe52edc0787ff3878d17b9bfa8e68dd8b47 SHA512: 0190d7e78993600f33da5923c42899bfce5411dba5457065d04f979458208a1b55a8f6c00c2031e9977d14bcae111c11e7d91f93cc573e4856a35926cc01b288 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18203 Filename: ./0.11.0-stable/libzenohc_0.11.0-stable_armel.deb Size: 4448936 MD5sum: 4c696c36dbb31573a945f5cf87b1fde1 SHA1: c1891b312326834e298bbbb7cdd46a1aa5df3abe SHA256: 26b332ccf7ccc0faac9b5b56121c865d84c8521299249847e8afff6f65cc24dc SHA512: ee108791ec50fd1ef0c3f4e368bfa432e3987e82413062983c64aae036c9ebc88266210f4956c3000ca3dd199a7595fdc6d6de01886a4916c65eec42accad967 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17957 Filename: ./0.11.0-stable/libzenohc_0.11.0-stable_armhf.deb Size: 4477864 MD5sum: a99e1abbc7a82a02fe46323514e73372 SHA1: 5a569404159b13602816fc07ba3c6a20e92b0e78 SHA256: 4ca77803f638bfec4f3b014a61d1b1c6c1483d59097c13dc1f0aba0fcd61649b SHA512: b107d0410dbf7990a2edcf42be444af8967e67c1197d2f5f925df73b9e087538457f9603a70f58c0ca3a133b722f2dcf22c0b6468d13f88511d0ce6b4541c003 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: zenoh-backend-filesystem Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21951 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-filesystem_0.11.0-stable_amd64.deb Size: 4688272 MD5sum: f0204f165aa1463130d1de175ee7b3d3 SHA1: d4a863572a139621f7b85e1b599de7dd430ef1fa SHA256: 4c757c89850463d361539a653fdac6f236399f4d92132fa9c0acb2627fc5c873 SHA512: 2c482cd6ca3f60aa6f0e8f831aa509b4b90306b08e21755831d03b7775fd400c2236f249e6a18a0da4aefe81ff37eea68011b7787b77433f864bfb961254fcf1 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19689 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-filesystem_0.11.0-stable_arm64.deb Size: 4208140 MD5sum: c93d5e9a48f42c18521db3aac5f617ad SHA1: 777dba14833fc76dd2e1f13063e03b48a0e17f87 SHA256: f75a7c823da1ca0a4237c3e77e5e6cbe0e2336ec7a29313c603dbe78e2d9fa65 SHA512: 61abddf4eed5baacd15d54eadf6909a11aacca8e2c3717ee265a354799fa44501fa96629fad17a00650a4f6586c7b392c11ea260f9f06143c3d824e23f512637 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16553 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-filesystem_0.11.0-stable_armel.deb Size: 3914064 MD5sum: 9811141fcd17405b15e9bc3feb769918 SHA1: 1ed6a67d75cdb71e09f1d5758460b69001e948e6 SHA256: 7c64cc1f738f7095c09690be16a2c26cbb5b207306ad9fd4c976ad7d954cee46 SHA512: 2e18e92399e705de0397c026fb7fc267beae2e3d97eb912371944e9ba626bfe9a82354ea8551161866e53aa328a51ff7db9cce07d68307edc5276938d112b564 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14817 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-filesystem_0.11.0-stable_armhf.deb Size: 4006740 MD5sum: 999846c517946262f43353dc94a9a9f9 SHA1: f9f1a5842a04f6f5662f9e15cbfc5a968906b58d SHA256: c452d074def7b6ff3e5d8c1ad1ebb73c49e478e0301a23c166a23649637207a5 SHA512: 0a497d8ff4b144fc43de39f1efcf61251ea216686b896177cce469abb5046fdb5aa061aeb4cd4b2c868a98a429b3a53efd794b81b1f3a46fc42b5bf1a9adbc41 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-influxdb-v1 Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16488 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-influxdb-v1_0.11.0-stable_amd64.deb Size: 3302060 MD5sum: 374614545592325bdf4db417158ac7c3 SHA1: a0073421b9060a8de2b51c40c0b2e7bc03ccce13 SHA256: 11547f536a1a980c271efe95b52dab72bae6b6e67bfc2f42e70e7d7e62b71fcc SHA512: c1db5d0f66621f5d78e19de6374476f60bf9ee5460aae754419393d93ac3198d9f5df58982e44ca451be07da157c2dd6c7a8f791b6b3636afae24070fa49d8b5 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14965 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-influxdb-v1_0.11.0-stable_arm64.deb Size: 2994132 MD5sum: bd75e7d250671238dcc060b725881c33 SHA1: c2e233d7ae2876892b5100af7abcac676a73d05f SHA256: a8940ea3ec9f95db74d8e6a79d08ca545bb8daff17c3a0a7faa8e04ce462acd7 SHA512: f49e6a99029982338b56abc486f7a72b77c62abc3e21a304755fd13a3034e370fccb6234340c12585023312a0b8e48f24b89417060f4641cbff5798108f02a45 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12575 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-influxdb-v1_0.11.0-stable_armel.deb Size: 2716900 MD5sum: b7321c36275a97271370d926598b1223 SHA1: 015ce0101dae81743e3efd330f2ed411589252c0 SHA256: 01ed5ae683f3a2dfada07d19d8b039e5963b259ea8f2f7393d1cc9b23c5a2b07 SHA512: c1109892fa7b6b0243272be611da8df503c6509de2aba4f379a2bbebe7d673f8a34f0512a44e3c5ce54ac5bb32d2471cf45f40f3abc4addbd21b56fb153bd228 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12494 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-influxdb-v1_0.11.0-stable_armhf.deb Size: 2716768 MD5sum: c2fd4355b6daab512c59baccaa8eb195 SHA1: a56f548c6081ae0873afabb6c2e3266f29dc450a SHA256: 83f035997c5ba94d82e4d01148f4f2ff299755606268d50c07815b0ac1046c9d SHA512: 21dc9c7d91dd27509b9f3939215c313e40600879d97d61c45c3e2a4a4ccec0bdcba190f75424a7db709d1ee974f7f140c69d12d85b32ac2257c4409b32f1462d Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19783 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-influxdb-v2_0.11.0-stable_amd64.deb Size: 4114688 MD5sum: 9cbe0362a57624c927e233973831e3b1 SHA1: 9d24667df02337f188ad7e2e2c57cf07d2d2e916 SHA256: 7d5e5496cd40c7c808d5f8460d63bf548e3c7e2edf9949138163900312e1f9ab SHA512: 9d80dbe2c24948f704339bcaa8c921bb4cf4dac001aab2f5daa482827ca00f31ec0817d4e667b25c1190c856fbbf5c467a2651dcb2e0c11d23f00dbcdd66b0f1 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18345 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-influxdb-v2_0.11.0-stable_arm64.deb Size: 3791492 MD5sum: 53c2655744e46cd9b4112be147c33251 SHA1: 808e498d26e21bca6b209c21be2c40dc6fe14e96 SHA256: 3d35bcc05cc1488b7a75edfc80c0a92fc19fdf234dae6c8b540ef3ac38dc08de SHA512: 3477ea17d0218e578cf08c8be0fd23f0a7aab42a77f4392d4d66a015089229e65946b65781c7951edd5599267d6eed96f5849fcff82d164856f3b4d84e1cc7ef Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15673 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-influxdb-v2_0.11.0-stable_armel.deb Size: 3483392 MD5sum: c0568bbe9a63a437b0ab525e23b86b14 SHA1: f7263fcf638d837680966b086c833b3b984a8549 SHA256: 98f6d6ce239e949cea7566f471cde13b34503940f922b5e1cfc91bb95aebb0d0 SHA512: 929e50f9bc4981c3b4fc7db785fa2639ba04c440fd5582bb214191fd8943ab2100ce2595dc2329795b9c051b757acd3f9e98302beae0bace38154af35e0b8c60 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15555 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-influxdb-v2_0.11.0-stable_armhf.deb Size: 3487668 MD5sum: 0ae1ac09a6bf09a1067690de91c6c740 SHA1: 00e784d33674935b0f7b5e8ecbcae7a392daf523 SHA256: d90e4f92b3a0582dd6ec3cc5a5d083584ca1ed8cb87290fe4523dec9c9f8485a SHA512: 554417a5c77b468277b44a9a2e4ac0da9f75cbd0d59c8520270d3c968e9e9765585173cedabf2f42b68125022e7163521fa171a95f71d4f5a9999ef73ae0d538 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-rocksdb Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21708 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-rocksdb_0.11.0-stable_amd64.deb Size: 4649696 MD5sum: 566fdd3b974ee6ae3f2d9dcc8a1e6d97 SHA1: 0812bfb375d1b6bdc328f768e8b20efe69234093 SHA256: aba104dc316960d546225344831c7a512cf53ca9b60de9f93b0406bac89f4514 SHA512: f76f1921d5d4d892f344a83c899790c46f74d10842ff5c56e216a34f82eb78d6880fcfeb32bbd905b4ca14a626ed40a9faffe13dbe9fd5569878a66a472ed80a Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19334 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-rocksdb_0.11.0-stable_arm64.deb Size: 4151872 MD5sum: e0138be7425115585e1e0646fdf682a8 SHA1: dd35ff7f266edd11ee6811bcf9f569bc7dcb8186 SHA256: e442edd137d80157c2ad6502bf8fb6602d11165a3345bbe9167cd2b11fa43954 SHA512: d0afe703c49179e98f618ebdf0c608ffb5e07bd0867cb904412763e7be0b7967df8fc86561c941c8c5690e1b7bfe978e9204e5182fd7d00e572746b729942272 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16345 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-rocksdb_0.11.0-stable_armel.deb Size: 3873312 MD5sum: 3a2cea27bd23bf9cd4bc085525eaa474 SHA1: 3944d751dec052b2b799fbbbe4b1898d156c9625 SHA256: 48e42d185b9da0bddd064bc609f1a6d6e472f11ed290875e74e0e6216acf9c12 SHA512: 7028cc2099067b0a861be9382ac3336c60afb96b251c672396e96cef97be8e3159b9d61da69308fcf4de2a5e37a2f1b340acfd9ac31217ead6799b484df1c1bd Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14568 Depends: zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-backend-rocksdb_0.11.0-stable_armhf.deb Size: 3974776 MD5sum: aab683329e1a72015bcbf4e75d6580d0 SHA1: 723ae860a2d66f9853ddd088ba72063075c559a5 SHA256: 18979c5fab0403246e3456aeaf8c733ed140cc9298331e99f91316cf211b2aac SHA512: 4d58803be05625b475860913357dcf6b021c52d7911fa623e0305b3da57ac6d90f8f8e49dfcc75bcb95811eecf42ffbadae376a4b5b5b4c29507e2bb858f0bc5 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-s3 Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26353 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0-stable/zenoh-backend-s3_0.11.0-stable_amd64.deb Size: 5213156 MD5sum: 6c3995bfc11a9b6e061871d1841aeb99 SHA1: 5a46c6e8858d766ea6bd6a4f6a1d468ab307243d SHA256: 9e1d9b5961a39f130f6f60bf77a1affc5489dc0d792c1701eb47a933156b68e4 SHA512: cace14f3a0c263605ad0f24a44889414cc83e0e3e0e0cf70a03d021f17d0f4af74a1694ecea0f1185ac4e83b0b03215aa7d0dac54a2fcb29b7ccb4e81d30a15a Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25050 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0-stable/zenoh-backend-s3_0.11.0-stable_arm64.deb Size: 4883312 MD5sum: 43b009ad3f285150c150a2f9aba9f464 SHA1: 6a3f33e97bc9fc4f5c0c80fef7c74f2e1cc4f023 SHA256: 8b5fd6f1039fa63cdd07340d8fcb8ceacafe85949d88b5adefad96eb923ecb4e SHA512: cb306ff55c590a40e78181ff7f326b36d194dde33e2734d7473647c85b8cff2f709b9e7fc35ec2d4bd7a94e06e5b51b507bae9a2acf6c117209177dd9b1d0d30 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 23424 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0-stable/zenoh-backend-s3_0.11.0-stable_armel.deb Size: 4735268 MD5sum: 4199a6b052c10448fbf6fb3b1da53383 SHA1: 0c972d6e7c5d8acaec5f997eac010eada2e692d0 SHA256: 179853ffc1450100f6fd876cbba373983f91400f65dc851344d85ab334f8d7df SHA512: a718d135f34d392fcde6aef31d58d9aa26264c915b16a8bcb12bd718dc978de99be481c36e8e7d5e09aa09cbb989f4df7bc342a23ad8f697c8388d500c7b7c5f Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 23204 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0-stable/zenoh-backend-s3_0.11.0-stable_armhf.deb Size: 4792032 MD5sum: d667e83b981bcc354dcdbaac8d4f3b10 SHA1: 3b82101fdd7d6be7b4af3715152b8e8220d3ec91 SHA256: 31424b127c75de5f8657f2c42733a4c6d5fcdbf75df33452fa6e8402c60c8c08 SHA512: fa448a839687f5a833dbec1cbda5752ad4e513bae95a5d9413901c01a905159e1bca9af3f1734be3a16463afc2b4cb9bc67b0f67df039344bbf82bcf77467519 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-bridge-dds Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21780 Depends: libc6 (>= 2.29) Filename: ./0.11.0-stable/zenoh-bridge-dds_0.11.0-stable_amd64.deb Size: 5352012 MD5sum: e0e2c025e25c4e440854741e20c6f06f SHA1: 91ecd83b656eab19e1815dad0b34d35056946de6 SHA256: 93154879e3c4aa57d54446badf51d53a5969978aae4ab65d0dc2023608fa2929 SHA512: 5236455a88e614e6027dcaa7891c8cf0f051028288346a10c0e643be8152ea1d8bca6cbed263cea96a709757e64abaccc5cc28419bc653402a0207c45495e71b Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19357 Filename: ./0.11.0-stable/zenoh-bridge-dds_0.11.0-stable_arm64.deb Size: 4793576 MD5sum: 6f63c971736f378b4cf62be11ae17ce9 SHA1: c78d87ac5b72111c5db35286c3b82c551510432d SHA256: 9f6fe801074b5e50e9f33a3eb294f95fac2a0d0f870a1aef227f04b09e83876d SHA512: 27ad3d771aa8ab5c1c7bc66e1f7f8ac8fb3b2d7d98f33c1cccba2fffbd8ee35b8c7a3b9171e2b458e57e4a8d2d040d1acc43bfbc59670d81d54d8504026f34af Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20537 Filename: ./0.11.0-stable/zenoh-bridge-dds_0.11.0-stable_armel.deb Size: 5116836 MD5sum: d49ef04d890716761186742ac1650874 SHA1: bfdd2ef4fec5789a10d2f0af85106c2d68548c28 SHA256: ad7c23cfe83087eaa13a08a737af3c5e1b4827d228a09879e82e0cd30e2d90a1 SHA512: c0ff326e5b5f6700d2e56d87bcf9a49d9b655690dc4fb81fec2559b969db04440a424a51c34b85006898757f6d77eea436e212d5e75162612c8e48798cb57265 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20043 Filename: ./0.11.0-stable/zenoh-bridge-dds_0.11.0-stable_armhf.deb Size: 5168360 MD5sum: 647bc00ce4abda737cb26c81ae40505e SHA1: 3a5ad5b7555013e902d48509d79e4458e4a9fc6e SHA256: 95fcfefbf67ca6d4295fa717ac10cafc45dd14054fa8f39885f979ced74c9eb5 SHA512: 2e8171a914c71484cec893f557e8fba2975a765f40c36cf783103f1327c08f4f275bcb07a509867cbe3dd5d6e1e9b6fa4667f6b0496f3c3779280110b9ff930b Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-mqtt Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21399 Depends: libc6 (>= 2.29) Filename: ./0.11.0-stable/zenoh-bridge-mqtt_0.11.0-stable_amd64.deb Size: 5069296 MD5sum: 900020d21495897ca21cf980fca91847 SHA1: 23923b62491a9263a39211fe61c58967fa750c70 SHA256: db1aad1c9325255e2417faa975c110512101d38435035c34a254b11d62352c94 SHA512: 16016ec1595811e466586d408b483b5e4cb671a361856ae4083a452a9ceeea24e6688c19e4860a561688ab2f06129838a662365eb2be5626c35d138f8324bcba Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18906 Filename: ./0.11.0-stable/zenoh-bridge-mqtt_0.11.0-stable_arm64.deb Size: 4529368 MD5sum: a14ddb9db562763369b47841ea07acc1 SHA1: d906b66bb5caf411f265b0f93715a9f7cf717a21 SHA256: 513842cfd9c60e00001bcf268404dc0de715f6592b07db980dfa40277e287995 SHA512: 0ee2a5e5597c7f5e498c40ae6753e2048b241a9b65efd394cac0bbe8410b0503baa2b41d3bec382cb56696c182d4168dbb09920ac4063e18105ac6b90a59642b Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20279 Filename: ./0.11.0-stable/zenoh-bridge-mqtt_0.11.0-stable_armel.deb Size: 4871200 MD5sum: d0c05d3a8b749086fd8677bb77305914 SHA1: 60c449d7d328d2d98f219c8c74cda40ca6beef4b SHA256: bdb1356e895369bb638a83ae80282977a83b64bf6d1660d9154a1465fd2d0595 SHA512: faa29a8eb7ee9ba2ca24af475563e65a0d6feb10a3bed6fd93b541540901e3d748d4ccef7f9c1269f31fc424625fd1fde4824bf2a68a46cde1a3d8b3de416334 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20010 Filename: ./0.11.0-stable/zenoh-bridge-mqtt_0.11.0-stable_armhf.deb Size: 4896588 MD5sum: 3d24eef0438a5bd4ca03f143390e44a7 SHA1: ca5a8f13f9c6fd1d3b5d23d5e186b5f5403cce91 SHA256: fc57a8b4cca78e56cccc5714f37985d337b0ce3aca51282fddc146aad76b24a5 SHA512: e73d24dba4f9f7484c4934aee73c2c68bced526ce5e2f0e305a3ea1c92fbc386cd483ca606cf65f331267185795235fc5154300d532fbe9fdbca9f607a1906b2 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-ros1 Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 22843 Depends: libc6 (>= 2.29) Filename: ./0.11.0-stable/zenoh-bridge-ros1_0.11.0-stable_amd64.deb Size: 5451820 MD5sum: c7778fd5cfe5f2225854b22c2c0f0b29 SHA1: 78dac381d1bc372bbdfaca5b6aaacc428435222e SHA256: 0c891a12288caa9117769e10c4b17b2e0de27c09c977f8550f11835f55bb8892 SHA512: 867fbd202b8217edbc17df83ecd7539d13e34e31518f15cfc73aec0d79512d45490aab34855be0b66d3a7d63ac42efe941eacf5083875d322614c7fc0130c70a Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20279 Filename: ./0.11.0-stable/zenoh-bridge-ros1_0.11.0-stable_arm64.deb Size: 4884060 MD5sum: 95bb31926deb09ee86a6a72664de892c SHA1: c678f632ac26535562503e39a5bf9c896aeb0f4e SHA256: baf2ddce3868b95ed25a0f962a56a9d5c66799a352550e04b448d7b45fadac88 SHA512: e00885f3541a48bf126c07169134480b3e86b50047eb9ffcfa8cd0c49f3fd7829229b3449fbeda79d771f78c3ba9cae19ad601fa608a36e5de17d50485e7321b Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21640 Filename: ./0.11.0-stable/zenoh-bridge-ros1_0.11.0-stable_armel.deb Size: 5253968 MD5sum: 16c23241f0c5a1bc343240abf040b8a3 SHA1: 510020b52648d5f9854b1dbca017ce5d14aed4d4 SHA256: 9137d5f42635141b787c8b2e68ecb44185ba410b6f09c1f45c52751c68c80d68 SHA512: 1a53c3a665b08cf46a5007a3c758e9dc354a6d410bc9e2a38671073dcbcdca3a824597193aca210b2edd989d317f0625d4c530f53c3fffbf658f8ee0f0c65845 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21325 Filename: ./0.11.0-stable/zenoh-bridge-ros1_0.11.0-stable_armhf.deb Size: 5278384 MD5sum: 2617e22542d8f512e59d003f6975cd7b SHA1: 4fe2128e24bbc22ccf68ad8028607c4ff5f71350 SHA256: 597135a298966d9033173457debe71ff87549df0799ab8f5774df671a88bee9b SHA512: 174205a707c5e2df5d13cb0521c258982b80df6b04c6292ece06fb0ad0f8214d78859906b6624c8200ff6ef8cbe03e1b097e8b7d0c550773df788d7fdfcdb290 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 22370 Depends: libc6 (>= 2.29) Filename: ./0.11.0-stable/zenoh-bridge-ros2dds_0.11.0-stable_amd64.deb Size: 5473176 MD5sum: 436c80363d1c50afc62324f996024f9f SHA1: 14813b29dd242289fe61c88d55284f85a65eb0ee SHA256: 8f10202c0163eae7182fb0a9fe397ac5531a089b7d2bdf889b8207cb1ea404dd SHA512: 5cc3ce4e869bbb8bdb5c9ac0d054f7963333bfc2757dbd60bdd7f4f8e92356c16a49fa1aecae9a1cd081640e2ca9fe9715601ece3372d474cb03473eec96e8c7 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19940 Filename: ./0.11.0-stable/zenoh-bridge-ros2dds_0.11.0-stable_arm64.deb Size: 4917184 MD5sum: bb06cfc8eccf74fa673ced3c3d8f9151 SHA1: f5bc0e8fd09033542157c25676ba7ba5cbfc7e6f SHA256: d5b29bbd6fa90f01587f812f47adb3b45b1546b5b02cb96bf1760dc847ce0b2c SHA512: ea4961c37c6e3cd637b879f5a8508c154314b999650a0cc9e3e043bb70ae60cf6e176aaa47fb7edaa5ab49ad19b65c367c0510caa9d265e4430e7dc0127812fb Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21134 Filename: ./0.11.0-stable/zenoh-bridge-ros2dds_0.11.0-stable_armel.deb Size: 5243492 MD5sum: 3ac032dde8ee6fb42434db34a745f669 SHA1: 30ffd30929355e0d236f33efd1836c363849a557 SHA256: 6cdde651467a9f187b16ee6beeefc8617852c98dd3edcd70ce8dd500ca4b0157 SHA512: 7878316d0c4433bd69effbdc00f128e7fd7bf38280c6834267d3de4167f4838443dc0533997f9c2a3fb15d767a9c44b66cb16b608c2a846178bc45e0cc3268fa Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20634 Filename: ./0.11.0-stable/zenoh-bridge-ros2dds_0.11.0-stable_armhf.deb Size: 5306176 MD5sum: 7fb30abc99d4e952eee65427f801391d SHA1: f9ec04e97eee5560bc34ea86cf99fd4a56e7c867 SHA256: 08a6c82488ec078d0ca7412c717834be9a2b64b02b2a2332ed53e990eafaf02f SHA512: 40afdbeb20b029abb2dc67150a8fa3a3130eac8ee2988be29c4328c9c75ca9b90c3e31d95054999b3186319bc144605f8261463c5ee9445ec017bb7bbde5a712 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-dds Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14132 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-dds_0.11.0-stable_amd64.deb Size: 2741488 MD5sum: 86613f6241221a655944e8cc54256fc1 SHA1: 2724b3feb63895de76db128603a8e03052e67541 SHA256: ed4a9edc49081e527ff6c3ae2025805228b06f985891191d6b1b0f05d0a2b50e SHA512: 733cf956255750c6a5b25dc66552c95298d50ac5ef1f4b3f04b748bb4e79cd9e4b4ef51d9d6ca91d6c1b8a0a058e77808e0adea7185df675a49fe73270b1cd8b Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12522 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-dds_0.11.0-stable_arm64.deb Size: 2472464 MD5sum: 0144866897a16e07c1ac51a5f02a00bf SHA1: f8439d45504d4568333cf3c08c6c9ef37389904e SHA256: db07d748437a6ade47ec3a47ea545b71414dec5bbedc421b57af56c6114c0004 SHA512: 05b7a5c1599abe62eeb27e6517836dc25e1faaeeaf152428440cef270f9e9bc74e53143d738a143e0bcc33849ce440d699af0305a661042c71ec7afedbd0498a Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9771 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-dds_0.11.0-stable_armel.deb Size: 2253700 MD5sum: 02142f70e6c5ed0b9a3a004181dc09d1 SHA1: 73516acad9d0487ad001a0579707b11f99e4fe13 SHA256: 30bb08489964bd657f2bf648b69976f15b5c1470a9d385e716e20ba3d52315c4 SHA512: dc4a3e9f0bd1be27b4c346abf6e46d2f47ada6edf61241bb2e003023b5eab9e9c21e3072f66ec9a59b73608834ab8b9a0a170d6e5ca2220aa9ed3aa0188e6cc3 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9448 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-dds_0.11.0-stable_armhf.deb Size: 2255240 MD5sum: f9ea75e62d7562243e8298286e90d2b0 SHA1: ddbcf5f92d88d45b02dab201114efc03fefd9d08 SHA256: e5a5d20a8ae1aac971aebf83b3c5a4a0f1af2870488f9aae37a66dbc74ef63e1 SHA512: bd01914d7e046e1b1188f6af3a8f8d5fafdf748137c87bcfef34dc5db8eef22ba749463f5ba227e47df04f33dc98d5e8ef52ee179a85d7b25d27696284b8df49 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-mqtt Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14774 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-mqtt_0.11.0-stable_amd64.deb Size: 2941132 MD5sum: 7d4baf51d70c29ab99c9a24743d773bd SHA1: c8ec813f6cc986b282aee87f4b598430f5f78cb8 SHA256: 70d2fcced7de4a02b4c29cd942825eba7a8f4440bfca1fac3cb1ef735622aea0 SHA512: 00e808e491c76a20e7318baa717ddc29bc5645eafec325e3dd1896fb26ce9e8b3b6075c57abecdf67226fc0ddfaa8ca5e82cd75c939182f531637ac45eb3b465 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13021 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-mqtt_0.11.0-stable_arm64.deb Size: 2621256 MD5sum: feec67b1ef6c739121350591e6d95cc9 SHA1: d2ea149fef7129452f2f3d4c53727d5a056ace53 SHA256: 2640c44be9cdd7bcf388fca8fc2a9cdf4343ad001c65dc26862d9419669a4505 SHA512: deaca3f79dd71e6698f01e2d94021dc83dd5e90e842354250dd31e0e7ca5c69430f474fce196fc148731f014f01a061e901f8fe9256952c053b000d6d563f8c1 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11167 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-mqtt_0.11.0-stable_armel.deb Size: 2429720 MD5sum: 447bfaff9c2f6a7618fc921579007335 SHA1: 6b17e9af668986fd0cd70a2fd407eec7b4474b45 SHA256: 6bde805e657880b1f8141722aef92aaf0ec413ea944bfe2d94e67270ca0f28fd SHA512: c5f35490755d554615418af179b9a134f0b6843f08d3c6e9e21125ee4408abcc2c504cd9b50f2c8de5748db76a4a379d686ea7cd5efe3afeef7c4d27806e1820 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11078 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-mqtt_0.11.0-stable_armhf.deb Size: 2434076 MD5sum: ec8b0b05db53fe22ffba22650e7bb645 SHA1: 9bc2131336cd1cc574a28d411fa88e06ada9a772 SHA256: 14358f2643e1778eb1d4197d674d6e498cdc3db22929de9283cdd83e01ebf118 SHA512: c276d697c385204c9beced0b2e1c174fdb774ee18d143a9e4e7a0d0512d7bbe05d4e75143bd47954156e39826c3935249b83821c90ca42b57c902ee3a44c1c47 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-rest Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12974 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-rest_0.11.0-stable_amd64.deb Size: 2382660 MD5sum: 8f7ffee26265ea1d9c1235dfaf5f51ca SHA1: b8a8664e254383185a5751b7ee17fde2a7f2f09c SHA256: a9c5d5e0ea9f7ac395658ff99867d5d26148c34c2d77f4c8f0e4352b99756030 SHA512: f2f4ea5fd1e7127053ddbd2b6959f6117d73d581b62f7a99141c41958079dc9e86b6134817b1198129db85ac23ae00637ca465c39e73d55a003576bcc35ab0ee Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11333 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-rest_0.11.0-stable_arm64.deb Size: 2137580 MD5sum: e558221ce159081a7d45859487ce7d3a SHA1: 5c55966ea3d63faf7497936b96aaabe5b2220e79 SHA256: 1d936f3249fa2043bceeb685f42603f626c18ef3fb6cd54b04dd783ebb6efe50 SHA512: a4a46c2a1473adbd5be30036719ff413d42c46061b586acf2ccdc7850339dd5f413d4740cc9f6edf36601551063b3280c841bb95d3134d9612f25d1966a7869a Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8703 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-rest_0.11.0-stable_armel.deb Size: 1931904 MD5sum: 62f9fea8ac39f9f060e41db479c80281 SHA1: bdd319e5d3208fc7afe7d51da08f0878cf0267a3 SHA256: d1fee5d6e6af0783a636211ba1888282e29b63f58b5f9e6b665f6c120b959a4a SHA512: b208825442857a0f5e2a6c1b2f0f1db0cb6ecb3dfd24849a946224d53f82c550fdf07dc0d5cb309e05c8415d81aaedd3608436ee425b037cc555e96908ab1113 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-rest Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8629 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-rest_0.11.0-stable_armhf.deb Size: 1919924 MD5sum: d5bbface5137252ae063e6ab2c7b36c5 SHA1: f9daf1caa1d70c3d7498e51d1b3ca709acad0623 SHA256: 56440fc6c1c700a5fa151f90197d94cc54995ee7c733a8b3682dd2c0fe1df3c4 SHA512: 535e1ed8ecab1812c166363c6dc0e645d1cb3529a1233c19e172c8ee921fa47251041fa350a0a1d25335afd00cb3db0ac0150f0cdc8e5583e4345e0d406a087a Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-ros1 Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16750 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-ros1_0.11.0-stable_amd64.deb Size: 3362328 MD5sum: 5e5d213f0dded4c17382e7b522c167ad SHA1: fdf26eb0cc8a01ade56a8870a859ae9616a9d7da SHA256: edb9ba974d989f631f0e454db8faf7cfdc87dc6390b445a951023ed6198151c2 SHA512: 78641f44effbe6bbb9250ae814f05334230e8746d0b1429503990ee17201ef8c2100c2d6b615462bfe3153f0f39c9b4071fd7247254ada1f9121ee4d0a56e00e Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14922 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-ros1_0.11.0-stable_arm64.deb Size: 3077312 MD5sum: cffd90be01942a19913ddc0b58119ebb SHA1: cf0825b31f59b5225e1e5b0a70c6ad6dba70c3c3 SHA256: f23dd46487b69819da89343d00fabd44a03602268c2074130f8f5fdf913f04c7 SHA512: a96b4b2ce8cc4c43966fe3673c81c3dc73d0097befbb4427ae38e77ad1d480b348d9c8fb81ae2ab501a5e4dbfa8fdf5823f45fb1a0f8e5dd08735fd0355a4ffa Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12381 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-ros1_0.11.0-stable_armel.deb Size: 2898332 MD5sum: 00794ecbb0e1e5cf37d8708760f51ff0 SHA1: b36cd2e874de4e82542fd4cfac7b7af0e1515e96 SHA256: dd4f1de058838d379ba1f9f755a879ecfbff47bc4938c61bed94186d852923d8 SHA512: 57007a298d1fc8d658511e804776f96d96fd653e8104118170c49c15b0d361547314f4f224020dd140337f46cf48fce3736c37b0ce3e26cd732112cfca271e5e Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12206 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-ros1_0.11.0-stable_armhf.deb Size: 2873704 MD5sum: 93c374413a794526154cef8091870aa3 SHA1: 652c0d803f9a346969b2421d2a49290a676c75e6 SHA256: e1f4358036a682d4f0cc119efbf588d55fd82779eb2ae0fccd0201295591176a SHA512: 0200282f4325b1639b6b97eeb6bac49d9129d5833f2356ba116d47abd41a02564cdcc23e9a75a54661c87ea39af201191377cc9a38bef128c25bb91c10c1fa28 Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14781 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-ros2dds_0.11.0-stable_amd64.deb Size: 2861636 MD5sum: b08809edbd974ff1c7d206cf58750a63 SHA1: 0f445f8cf12b3bef01397e810e44130ed91c9429 SHA256: 550a014e794fef77bf910ebd04638bf1677ca2b60ab9b6d0a601c7f001d891a5 SHA512: d89993c7db2533348b164a8d68ba94e9726da267de8034ca2649224e3150bb1fbefcf58d3344259c3f8c9a7f060c05e5784170ac53bb2e0a60156e785c4d4514 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13064 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-ros2dds_0.11.0-stable_arm64.deb Size: 2583424 MD5sum: 88f0a7dd0cc1f02d129c4eecbbab1e12 SHA1: 0119c10497c80907e147bd793c4500dd65e71865 SHA256: 50c498852a70e393359e67eb83f8dac6e8c86607d76105d91b8ae1ee0233e52a SHA512: 63a76d7323f29ee976f33e113b7d5e43b5c64fd2596e4a28a5004bca55f3cf9d47a94f6cd3d0efae06ba95570338f1992ad28f39c88958ba56e212fc8567581b Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10361 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-ros2dds_0.11.0-stable_armel.deb Size: 2377600 MD5sum: b789882c32ecac1045a8f39dd436de68 SHA1: 335890733d62ec6e8a2889267449f716cff2cf81 SHA256: 7385b6b2b5826f929fd0013e76d28bcb219eea3cfcc85019030270de36bdb765 SHA512: 886bd31118d72df9dd47e3a55e3faf8b7b7e014c9a1a6559c9ca05a5370fa2da1fe532a43adfa7063f0857671e0f51745b7ea22df6ce54cf452e5681a46023e4 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10026 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-ros2dds_0.11.0-stable_armhf.deb Size: 2384620 MD5sum: b40deac8f1a80c80962d2a07a43a38b3 SHA1: 2f1127c95993dd24ad26ebb5bf6e94b9bfa27e99 SHA256: 02cd040ce682385b9d7b13dc29a8e47238bc86792476f6b3c1a58757aa5bb953 SHA512: b95ab28cfb36fb64cdcf7b0624d8eda61d432e247914e92abff79aa849234ee9dfb98c07715eda2c6a46dfcc7a2a39f2c609b0172f3812bcadf6717687998812 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13201 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-storage-manager_0.11.0-stable_amd64.deb Size: 2406496 MD5sum: 87a2f0b903dd37495c729bf5218587ad SHA1: 6b0991ae5c1c09c1c8ae89bd3ec5ef79f682ebed SHA256: bb235788d57a02c8641de20f6d0fdb4998af22087dc46d1cac1a2cd0d3538c77 SHA512: 4120b5886940c43f12b5657183a21494832f795503cbc44d5eb1f4572212021b97b3b5a761ffbc7a59f5ae9486d985fef8b927e1300a907800a59fcceadf067b Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11538 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-storage-manager_0.11.0-stable_arm64.deb Size: 2162388 MD5sum: d3118dbaf26f8a951a885411f57faa72 SHA1: 6400f28ae7edfa1d3bbf86bad5ac06ee6cb14981 SHA256: d8ecd920ef277ab4a688ccdc4f41cdb74e060e9ae28a1fbcfa15846c71cea7bf SHA512: 2e06a58d9924ffc3c9f70310b2cdac9e5d0d093c90b24dbfc2ef8e50bd9d57af65f720114199553525624b67f62c2ce9eacf766efc4b8bf31a46fb50e405e4b0 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8958 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-storage-manager_0.11.0-stable_armel.deb Size: 1978392 MD5sum: 0191bebd74f75188c0f8a79314de9650 SHA1: 7f89bf945c96351c5a80f170c518a96b0d6df258 SHA256: 62f37065bd47f748b2f4b389bb631afb90831a68a3ca2fa38ec749928df6f341 SHA512: fd9eb82fd9791a32d17983b519277bf4f3eade34cca4419636ac604222e997b4a143ef9b1fb1bd9de63e4971741478135448d05f24e397afec1c2cab0e985a1a Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-storage-manager Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8876 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-storage-manager_0.11.0-stable_armhf.deb Size: 1967712 MD5sum: 05bf29a795d3efcb26d616e97f9d37fa SHA1: 0c18a13480e2f61bcc044301c1eb6c403ea1cce1 SHA256: aa37b1c9e816c5c1ddc2fe10dc3d1b54f37dd29bed7a8a6f7bf5f986e12864c5 SHA512: 0d8b8c2cb822f4ead04ec32e053579a62643b7adee7e2e55367508ab55f6ea780e6f6ad104d2a11999a08ac085ef84f0f119c4d33b117be21ba2f835c4f7e105 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) . . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-plugin-webserver Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16118 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-webserver_0.11.0-stable_amd64.deb Size: 2936076 MD5sum: b7370e384f28bc49975a19ee62ee6985 SHA1: ab8893674227e46123ed848dc05ef420fbd65c91 SHA256: b3428d9096d2730c4dd2716e1b2e1e5f3933f337755f0ca55dd568e221204c14 SHA512: 3b9d13d458cf21734f65e25d229c39817bf7fdc6da467b9570f9906746b74f00271be868fd508ea69d9ca2537b4473019717b47dc3771b02447731a95172c7f7 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14735 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-webserver_0.11.0-stable_arm64.deb Size: 2695792 MD5sum: cbf17613a2a4103a32ead66f3ec4ffe3 SHA1: e1eb020376d778724d7bb8cfb891a6e99e515a60 SHA256: 59318ced6066cb73c099a1741edc9347089c7ac9d526742809389927e035f9ce SHA512: eae6ff1ba16bc1d1d5ee60a9cee634757f1576bdbdd98d76017f050de1ddf9725695221e945c3f985f8c6c1105163d69df7a5587109eeace31029ece3012e6b3 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11584 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-webserver_0.11.0-stable_armel.deb Size: 2404084 MD5sum: 9a26edf274ea26ec5bbd69d6e08b3d49 SHA1: 3dcb6431c6627e9072022c3c28a5e45ab0b757bf SHA256: 600c65db85275f0b71d3f4b241cffaef28a471de4769f3011ffb1424334a7b31 SHA512: 4fcbb7fbcbd12dd944550f1ff6fb785a43a522b9d0c248b2300646b134e7a92042abb2b02c88412116ff72faa9eb651c80c0480d1ef462071b6ef8fffdc2c363 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11503 Depends: zenohd (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh-plugin-webserver_0.11.0-stable_armhf.deb Size: 2386076 MD5sum: 11e1c6a887e42bcfa2a939a9e4655379 SHA1: da4f7b0e88c1559a769f7c99072d4f2c3a9db0f4 SHA256: 2cf3d79944fcb4e405dab80aba433dc57199d27a2750d6cd7d23a97b7562e9a0 SHA512: a9c45d3183707f75c076c7ab99783186bffc9d08ed291d61565d7c46c5ef8f51783bf0f356efd26a457f576d51c27866d4bbf6f065408cd365f621bff3de2bd5 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=0.11.0-stable), zenohd (=0.11.0-stable), zenoh-plugin-rest (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh_0.11.0-stable_amd64.deb Size: 17500 MD5sum: d3926b2608ea2f76270b3a444d41ad12 SHA1: 67ff9c2e317585ff58f17d218685f05697279ec6 SHA256: 1c562a12456fa26fda0bdbdae3d69fbbf00e58134f137e29a1a67a9627f77aed SHA512: b62064ffb986a32b781088d7b1eb45ceb67f8b265566c41782a831a810fa2049b649570ce983937c3f4850b7522f386e8c7039a0bcc698e52e4cf57e3a2d14e1 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=0.11.0-stable), zenohd (=0.11.0-stable), zenoh-plugin-storage-manager (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh_0.11.0-stable_arm64.deb Size: 17504 MD5sum: 832e70449e90f038f891204e6d1316e0 SHA1: b08c44a5d5b5ed5452c5ff0e53026c39ff08c2ee SHA256: 69132c15c8ecd8b56d41e47bbf03a5d002671e6661697dbff4d09295e72c1816 SHA512: 4be880985de82d7f2d2ca45df4c2aeb023574f5c5b48c65ccc15f19b72bcc49ab509586c0a20a13a3ea8965e637ba484d21d3e28240f322ceefe70d3e1e86bb2 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=0.11.0-stable), zenohd (=0.11.0-stable), zenoh-plugin-rest (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh_0.11.0-stable_armel.deb Size: 17504 MD5sum: fad5ef0fa7fd8e4f36f14cd707981bff SHA1: 98bbbfd458d97a1b3500224fe6752bc4b4408cff SHA256: d288a210ae75e5175c25486d111c7fe42fc25f1a29f1fecb93b46200caadbf2b SHA512: 6ce142ced8b245597ee05afa7cf785685039264efe980a396ecdfd5ffb6c3bb73d4c31dcaa3cd1a3aa4a8cfc9f7044de131362a8ebd97422191328a0bf33c461 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=0.11.0-stable), zenohd (=0.11.0-stable), zenoh-plugin-rest (=0.11.0-stable) Filename: ./0.11.0-stable/zenoh_0.11.0-stable_armhf.deb Size: 17500 MD5sum: 46dad62d2bd65c7e3a04a64f85d0f905 SHA1: d2969d16a2f71efcf57cbc99d7a4aa595cc89868 SHA256: b026b79053f9a0812181789122922c5eedc1bac33edb03a2a9086b8957784e56 SHA512: 39fac43d7742a228f17112b45d58ef697551da45df20871ec87034bc1cd07e04d47269be52f937fb78a15c2dd089e22d23aa21ebe76c99b70f8bc388949ed6c3 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: amd64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19746 Depends: libc6 (>= 2.29) Filename: ./0.11.0-stable/zenohd_0.11.0-stable_amd64.deb Size: 4685080 MD5sum: 8a62f9dea1acb104baad0d197e20f5ba SHA1: b3af9a302707f508ccd5bad77cfeb513c381f502 SHA256: ce30e19bbc1a5802093e35f451bc779691a27ff538c2eaf2c8de8edb70cef789 SHA512: d4f29b10d82ac514f6cf16d5a76d071e4b0b818bbb153d2685458dd3d31656ade1dd1b7358e8312bdd716ffac47c0542cf30cf1af1d8fb9ea9dadb5e6a7c9bf9 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: arm64 Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17106 Filename: ./0.11.0-stable/zenohd_0.11.0-stable_arm64.deb Size: 4154760 MD5sum: 3b3ce38f590b0c92aee15bbc7a1f68ff SHA1: 21d6172cdb42f4ecba0c80efbc5993b44af329aa SHA256: ff50e03b5440298144665ae792cca6679babc068a83015a934a3a20f4b7fe9e1 SHA512: fda7704006132830745e72bedb614098d430085a08321bf00ebf780029d325eb8ae9aa43d4948c12793cd70957f9d2d7ba4eb5cb9684cc615e47a90aa1c2978b Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: armel Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18604 Filename: ./0.11.0-stable/zenohd_0.11.0-stable_armel.deb Size: 4561216 MD5sum: 3045ea429dbb25b0ffe5f71645b3b774 SHA1: dbc42d50c2af9297b287879a38fa9b340b7d193a SHA256: 8c3498bd0442b1751893c1d2db5f129cc8d88293415d789bf39a6abda786b0b3 SHA512: bcb372812efa7fb245df715b44dd11c396381ff7af3751299c5106fbda4c47ff5832ab563850c2f7e25808aeb9fb4e220b80c00f7b0ea21131533de85d9bda89 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: armhf Version: 0.11.0-stable Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18359 Filename: ./0.11.0-stable/zenohd_0.11.0-stable_armhf.deb Size: 4614460 MD5sum: d3dfda7d9d734844fe59be29dcfd907e SHA1: dac9c951b58806afa423d82bc23002e1028419e3 SHA256: 4029620738b664bc355b3d299dd6744a1d87836188bf5f94a051b84d099d0ff2 SHA512: ceda93f11283ca8bf6c68e3fcc9248fdf1e9ec0eed93cb2a1de8d2819a20d8e9e01521bd9697cf31fc03d8ee5b1a9794d9ae2042ccd621c9ee53f69e3ca10d65 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## Getting Started . Zenoh is extremely easy to learn, the best place to master the fundamentals is our [getting started guide](https://zenoh.io/docs/getting-started/first-app/). . ------------------------------- ## How to install it . To install the latest release of the Zenoh router (`zenohd`) and its default plugins (REST API plugin and Storages Manager plugin) you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it where you want, and run the extracted `zenohd` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh ``` Then you can start run `zenohd`. . ### MacOS . Tap our brew package repository and install the `zenoh` formula: . ```bash brew tap eclipse-zenoh/homebrew-zenoh brew install zenoh ``` Then you can start run `zenohd`. . . ### Rust API . ------------------------------- ## How to build it . > [!WARNING] > Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.71.0), so no special configuration is required from your side. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To build Zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . Zenoh's router is built as `target/release/zenohd`. All the examples are built into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router. . ------------------------------- ## Quick tests of your build: . **Peer-to-peer tests:** . - **pub/sub** - run: `./target/release/examples/z_sub` - in another shell run: `./target/release/examples/z_put` - the subscriber should receive the publication. . - **get/queryable** - run: `./target/release/examples/z_queryable` - in another shell run: `./target/release/examples/z_get` - the queryable should display the log in its listener, and the get should receive the queryable result. . **Routed tests:** . > [!NOTE] > **Windows users**: to properly execute the commands below in PowerShell you need to escape `"` characters as `\"`. . - **put/store/get** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell run: `./target/release/examples/z_put` - then run `./target/release/examples/z_get` - the get should receive the stored publication. . - **REST API using `curl` tool** - run the Zenoh router with a memory storage: `./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, do a publication via the REST API: `curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test` - get it back via the REST API: `curl http://localhost:8000/demo/example/test` . - **router admin space via the REST API** - run the Zenoh router with permission to perform config changes via the admin space, and with a memory storage: `./target/release/zenohd --adminspace-permissions=rw --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'` - in another shell, get info of the zenoh router via the zenoh admin space: `curl http://localhost:8000/@/router/local` - get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/volumes/*'` - get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/router/local/**/storages/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/mystore` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storages/*'` . **Configuration options:** . A Zenoh configuration file can be provided via CLI to all Zenoh examples and the Zenoh router. . * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file and the available options. . . See other examples of Zenoh usage in [examples/](examples) . > [!NOTE] > **Zenoh Runtime Configuration**: Starting from version 0.11.0-rc, Zenoh allows for configuring the number of worker threads and other advanced options of the runtime. For guidance on utilizing it, please refer to the [doc](https://docs.rs/zenoh-runtime/latest/zenoh_runtime/enum.ZRuntime.html). . ------------------------------- ## Zenoh router command line arguments `zenohd` accepts the following arguments: . * `--adminspace-permissions <[r|w|rw|none]>`: Configure the read and/or write permissions on the admin space. Default is read only. * `-c, --config `: a [JSON5](https://json5.org) configuration file. [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) shows the schema of this file. All properties of this configuration are optional, so you may not need such a large configuration for your use-case. * `--cfg :`: allows you to change specific parts of the configuration right after it has been constructed. VALUE must be a valid JSON5 value, and key must be a path through the configuration file, where each element is separated by a `/`. When inserting in parts of the config that are arrays, you may use indexes, or may use `+` to indicate that you want to append your value to the array. `--cfg` passed values will always override any previously existing value for their key in the configuration. * `-l, --listen ...`: An endpoint on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default, `tcp/[::]:7447` is used. The following endpoints are currently supported: - TCP: `tcp/:` - UDP: `udp/:` - [TCP+TLS](https://zenoh.io/docs/manual/tls/): `tls/:` - [QUIC](https://zenoh.io/docs/manual/quic/): `quic/:` * `-e, --connect ...`: An endpoint this router will try to connect to. Repeat this option to connect to several peers or routers. * `--no-multicast-scouting`: By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature. * `-i, --id `: The identifier (as an hexadecimal string - e.g.: A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random unsigned 128bit integer will be used. * `--no-timestamp`: By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature. * `-P, --plugin [ | :]...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. Accepted values: - a plugin name; zenohd will search for a library named `libzenoh_plugin_.so` on Unix, `libzenoh_plugin_.dylib` on MacOS or `zenoh_plugin_.dll` on Windows. - `":"`; the plugin will be loaded from library file at ``. . Repeat this option to load several plugins. * `--plugin-search-dir ...`: A directory where to search for [plugins](https://zenoh.io/docs/manual/plugins/) libraries to load. Repeat this option to specify several search directories'. By default, the plugins libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` * `--rest-http-port `: Configures the [REST plugin](https://zenoh.io/docs/manual/plugin-http/)'s HTTP port. Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface) - `"None"` to desactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . > [!WARNING] > The following documentation pertains to the v0.6+ API, which comes many changes to the behaviour and configuration of Zenoh. To access the v0.5 version of the code and matching README, please go to the [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh/tree/0.5.0-beta.9) tagged version. . ------------------------------- ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . By default the Zenoh router is delivered or built with 2 plugins. These may be configured through a configuration file, or through individual changes to the configuration via the `--cfg` CLI option or via zenoh puts on individual parts of the configuration. . > [!WARNING] > Since `v0.6`, `zenohd` no longer loads every available plugin at startup. Instead, only configured plugins are loaded (after processing `--cfg` and `--plugin` options). Once `zenohd` is running, plugins can be hot-loaded and, if they support it, reconfigured at runtime by editing their configuration through the adminspace. . Note that the REST plugin is added to the configuration by the default value of the `--rest-http-port` CLI argument. . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): This plugin converts GET and PUT REST requests into Zenoh gets and puts respectively. . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storage-manager/)** (managing [backends and storages](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes)) This plugin allows you to easily define storages. These will store key-value pairs they subscribed to, and send the most recent ones when queried. Check out [DEFAULT_CONFIG.json5](DEFAULT_CONFIG.json5) for info on how to configure them. . ------------------------------- ## Troubleshooting . In case of troubles, please first check on [this page](https://zenoh.io/docs/getting-started/troubleshooting/) if the trouble and cause are already known. Otherwise, you can ask a question on the [zenoh Discord server](https://discord.gg/vSDSpqnbkm), or [create an issue](https://github.com/eclipse-zenoh/zenoh/issues). Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: libzenohc-dev Architecture: amd64 Version: 0.11.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0.2) Filename: ./0.11.0.2/libzenohc-dev_0.11.0.2_amd64.deb Size: 32164 MD5sum: da22b4128af4f0c342c79a9e6b4d64ca SHA1: 818d73114199d29e70f3cee66b43a21efd8363ed SHA256: 2c72c34e9f91bc8317fe2758aa7c925f941d3530193c9b9de77f0fcbb63c56a5 SHA512: 13446c54b010cc84bc8a94e32cbfce93a147d8dfdf4fe317135be11086251234c342f041709d2dd184c383c8f132c018c4e5ac54885a3130de9ec2bcf7cf9996 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 0.11.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0.2) Filename: ./0.11.0.2/libzenohc-dev_0.11.0.2_arm64.deb Size: 32180 MD5sum: e24cb9c7519b5f358af4d4a16456926b SHA1: cdcb6efee56fb39d5263799c8ef67f4b60b5f013 SHA256: 9af2c16a86cec06e20ba630c1c83d3db951cbf5fe740fca896a757fa0c4c71ee SHA512: 5265d4dc74f79e2a7f12971a2e8779aba6afc6c1b4ffb9d93c6d2669d7f268863dec1eb575086ca05b53c0f4da222c5ed7425ee51676c1ebbcfc182cd047391e Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 0.11.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0.2) Filename: ./0.11.0.2/libzenohc-dev_0.11.0.2_armel.deb Size: 32176 MD5sum: d81e451c0ea5baeee84187485c384067 SHA1: 0f3bba03e025e5d7d4c6af9e0e213ab4af091ce3 SHA256: deab55c239cc02b8f4974e6e637ad0e847d83ea7a0a9509ef9d77e8995ac0da1 SHA512: 710ae3d0070d99698f713bf5493b440b1c18c231c69f6db4fadc1b9f6695a7203d70ab4ad5e4a1dbed56e9e5867ccf5d07d7c2329db38a8bb362cb3087188a2d Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 0.11.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0.2) Filename: ./0.11.0.2/libzenohc-dev_0.11.0.2_armhf.deb Size: 32192 MD5sum: 6c6b1a4109b2ceed14a6d221186479ad SHA1: 6518b1083aba36bb339fdc6bc6db0b7a1bec7d47 SHA256: 2ad1df54d07cc4dd297fa66f034ed68228097f7cf87b0c99b25e4d52cbbf7476 SHA512: 2d290e0977fbb4f97f339222d839fa44b735d5bc15e819b5de9be98de0c3a79ba08d5932ad38fc90d37727b006bb22373c2fbba31f53da1acc812955dc8861bc Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 0.11.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19370 Depends: libc6 (>= 2.29) Filename: ./0.11.0.2/libzenohc_0.11.0.2_amd64.deb Size: 4624996 MD5sum: 2f63c15caa67434fcfb2c913430b655f SHA1: 058e0562e23bbfac847a483e5d8db59a6a9675a2 SHA256: b792c5a2a6bdc91e7728aa2e0360cf5128fb95645bb473addd60b4f958fe953e SHA512: 86a6bfec64fb15808f2af88338aedf15eeeb45dd007d63b830aa6c728b390e383aca8ecebf51ad1adefa441b9ea07f4c77b36aa5c6ab6dcb9c85635eaf0d857f Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 0.11.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16891 Filename: ./0.11.0.2/libzenohc_0.11.0.2_arm64.deb Size: 4102232 MD5sum: 998df8a74540727d893e0d368e6e1f3a SHA1: f1ef8b59bbb4f96bb2ee754ed2f80b02bfb9bada SHA256: b311413e7fb97826a70680d9cf920cfccc35e728711d8ef2caa6d39c1d6436af SHA512: 155e00242b97c76f0c593a05ce5f1e44bf211dc885747a53ab0930a755e3dcc7c093d8d862738a297da68bb517f85784e8c8eaccc4493203c8118cee26227962 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 0.11.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18207 Filename: ./0.11.0.2/libzenohc_0.11.0.2_armel.deb Size: 4445092 MD5sum: 7e3969a0bc21eeb6c61c10762d07b76d SHA1: 73a437d9332f5865b9645f060bcdd4846580b52a SHA256: 44397bbb59821cc0aea417a769ca70eec867a7361ed27104e0b77cf47551d555 SHA512: d672263fc63d2f3ad25ad7c9eedbc4881c3608ab30a714dfc38ea3152e82a8be08138125a71a1e6e6c5be3451f89147c97870d224ed33146a8f197881952c10a Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 0.11.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17961 Filename: ./0.11.0.2/libzenohc_0.11.0.2_armhf.deb Size: 4479948 MD5sum: 017654baa227d7bd2ff6460929ee2870 SHA1: a7ec2148aa00e9a41c391288511a947acc7d52b2 SHA256: cc49cf354e1490cd140a936b750f6e6342a60e56119350b26774faa62d5d2f23 SHA512: 600f733d81334b3b41f0829a730acf93a04bdb830c37f5224fc22a8832d07900e689f1eca94daf49714a6b52dd62002e9a9542890bb6a1916f81e9f30e534228 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: amd64 Version: 0.11.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0.3) Filename: ./0.11.0.3/libzenohc-dev_0.11.0.3_amd64.deb Size: 32172 MD5sum: f487cdc254eb815bde691067df17d3b7 SHA1: f8a08bf168d73e09fbb7f3d6f484ca117e12bc9e SHA256: aadd33344fece05122d7d99857d1372dd9ea4a348ecfe5af3fb6f53b8475a99a SHA512: e264574cf0a6e86997d25a09e4b34b29ed8172fb062acc81b91f900220de64d2595db91b945d4ef5ed7805d0d1a1180fbd4cf0092f7b1b06f7d53dc951733452 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 0.11.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0.3) Filename: ./0.11.0.3/libzenohc-dev_0.11.0.3_arm64.deb Size: 32192 MD5sum: d5629cf0d9bd340928d56e3cc643303d SHA1: f67f0461f08fa46c281e57b70e1714807bfbc891 SHA256: 9568a85433c680e236d8e80cdef56c7e5b2bd927b7e5af30733cc6b1b0c4c2c0 SHA512: 48dfa473cf877b8200f7a4b3faa08742e1831c26d65080bb164569016e8e6ba38065abb98159d3879dc5e3f79a29b23e10aae917ddae663addcf1bc7aac0fe84 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 0.11.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0.3) Filename: ./0.11.0.3/libzenohc-dev_0.11.0.3_armel.deb Size: 32172 MD5sum: 8147c1d8e122c8e3fa72cb038bbea401 SHA1: 744bd89ed1d387c8ab29e26f38465df6689be20f SHA256: edec49be67b62bdbc508bb53c9484addea73aee32c0ed45084d6350d4e6671c3 SHA512: ea5eaa1209c2a1e35ba04992ff9bea30e27f5f428d63b3cf9503158c3a2c8cb2f8914c4106bcb5498e3088a280d1f97f23d0fb87cf49eeef84c096e0f9804324 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 0.11.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0.3) Filename: ./0.11.0.3/libzenohc-dev_0.11.0.3_armhf.deb Size: 32176 MD5sum: da6039c0d79534065877956951019262 SHA1: c79c980105ffea4954e9215364e808698dc938ed SHA256: 392070a80758e3777f8b4ad7eacb0096745524ce58ba2e58204198013a96f2f2 SHA512: 98133ead7c01097b623bcd7ff0893b420ad24f951d279c9bfe9a06280482e3dafee941f2074e47455c72180ce97ff13173957b90774f6167f90614590195adf2 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 0.11.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19362 Depends: libc6 (>= 2.29) Filename: ./0.11.0.3/libzenohc_0.11.0.3_amd64.deb Size: 4625288 MD5sum: 235c55eb42667b3ea024cdf49e4fc87c SHA1: 84f6d29a01a03a87419ad5d336513b4a83837b26 SHA256: 87d3832db552ce15c3db8ca333452e976c9c7cf6cb8fb05de2802eebe40d063c SHA512: 53c334620c2a7a191a39929e4adbce4fe722500fbd49c68513f20bdfc5ad30d33a04d840239f7dda05321de5acede37886ea21b9b8093e4e4134517c87cccc7e Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 0.11.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16881 Filename: ./0.11.0.3/libzenohc_0.11.0.3_arm64.deb Size: 4099864 MD5sum: 52f0834714c4a3307fdcc3f9b2433459 SHA1: a76b115797d1b20acbc526e276c14a32e7f927de SHA256: 90f7363255a135e306b9f2fa9f7b641f6e3c3c466f146906669b6757cc88bde5 SHA512: 9e5344982dc5e1192650c04a9da71b79f89bb96111c66144403954e71d75376a43fc7dfe99032ee4a3fce5027f72b484436f831282b1644e31c0caf2619b8eb2 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 0.11.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18198 Filename: ./0.11.0.3/libzenohc_0.11.0.3_armel.deb Size: 4445492 MD5sum: da1337111fe343050060321343df04bd SHA1: 38be83495939368fbc07656ec9201d0323901b23 SHA256: bf6a542cd693ff9e474409b23f3eb00b1bcdc35d04b6f022d8446f3abbfb202d SHA512: ea258aaecbfc3a0456c3636a2f61230cc309e522dc928f9587adbf9a88f10de038311da283dd487dc6c0194a89697df2559f0f945dfaf0ed299f30dc69edf691 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 0.11.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17950 Filename: ./0.11.0.3/libzenohc_0.11.0.3_armhf.deb Size: 4474688 MD5sum: 175fbab508785d69f4e399800bc23e68 SHA1: 912a7642da41e1b68c1bdf5713e7b2b01f45eef1 SHA256: 1ff97d0ed7409859c77dc6a4900b9053fb13baea91018fcfa838f93348b00deb SHA512: 7b5af98ade088cab3f7b589cde30a6ac7137ea5b7f8aa0b97fd239bf7630d0215a85fb16714a097f21a17df0d7b6574dea58bb7479495147be6d76d3cb8a36ae Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0) Filename: ./0.11.0/libzenohc-dev_0.11.0_amd64.deb Size: 32304 MD5sum: 40dd4ab9cba6a045082e11a8c88e0f0c SHA1: 087f0f5ab01e3f223fa29426c5c5397541050d7a SHA256: d2dcb632b009cbd9f6fb750213d7fa506a25647031a1f8be9eab229e0bdad32c SHA512: a096f20e5c1785bfee2c7556f915dc7b1682d0d3892481f80d48c5c240fa803787355732e512b1c6a6f6f9a8fa3313263f195058e8828905966714db93ace321 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0) Filename: ./0.11.0/libzenohc-dev_0.11.0_arm64.deb Size: 32324 MD5sum: 5398380d8ec4b61ce7caddb47afc8fc6 SHA1: 3f51c2088c1716807a9e00ee8ed58c662ec8466d SHA256: 6d9a188472a51092f329d3595f90817d515f772af79245fe2c22ea7e42093689 SHA512: c8f9603106ef2f6cd1b254f7b0d8ccf595742ee0f5aac20188e734997e7419a5d9a3a32b205db798bd90fe5bc7390dad2fc81e34da4662f2eb00d4fece886647 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0) Filename: ./0.11.0/libzenohc-dev_0.11.0_armel.deb Size: 32324 MD5sum: 196cc2693d549cae80f1fd9634f1b45d SHA1: b6cbf43c9560a182660f0268cb43a59b68c435f7 SHA256: 1ec9586f7788cb8e2d7db9562aa6fffb35470a7848156c81b730fb7151dd22db SHA512: bcf32f2801604039c0b05d26897ce66afcb8dba301bd44abce3c83dd1742d70dcf9cb5488101028d7144480ba912e9fe112d14406a76306358115d061935d6d4 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 173 Depends: libzenohc (=0.11.0) Filename: ./0.11.0/libzenohc-dev_0.11.0_armhf.deb Size: 32324 MD5sum: 2e40b5e40a8e91f69f4fc50cc4cdb6e1 SHA1: 5b40bb2ccbdcee6b399546442c3f8af575a0b8e2 SHA256: d288eb6585ac24cee02cac15edd74aa42bb3284543e6e26890e97211a82daffb SHA512: 38f4627f89d1f94c755f70ae04fedf6aa13e12c60ce2cc4b5129c0bd20e73dd68f4b6ed363fea596c50ae7ccfbf107ccf9a5c163f08719abb2604624723242a2 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19367 Depends: libc6 (>= 2.29) Filename: ./0.11.0/libzenohc_0.11.0_amd64.deb Size: 4627236 MD5sum: 887efce149d070c3f75c5286b824f0b6 SHA1: 3c8107e81f861c9cf6092e3b3b6e3249c9365a57 SHA256: d9b51937fd512947811e5026497fb742c530579bd22fd6805ea91952ee7b1dc3 SHA512: 7f7f38e7149d460a9d183667c18d6b58bf70457815c666d80a6451be87b171676dc06b8b3d759836e7c6272caa50abc1a756c0c03cbc34eb6f07bdbdd8f3215f Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16875 Filename: ./0.11.0/libzenohc_0.11.0_arm64.deb Size: 4101712 MD5sum: 20bae538da3c9550ee1ea9ec5d6ff52b SHA1: 3367e672b8b412d8a1d02f87661a298c0d751bb9 SHA256: 26e55e9edb29583baa206f0dd219bb06942b6e2e021a77f34194e8a754a72d25 SHA512: e0156d9a8ef6f19fbcab00ad08485bd6d875ac74ab5b2a708aa838efd3efd31956324a3c66ddd85fc471fe090bf1b131ba43dd52714f9e981bbdca21c3fbbf6c Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18203 Filename: ./0.11.0/libzenohc_0.11.0_armel.deb Size: 4443840 MD5sum: 13e8c30ec52fc07d68106254c67ab2ce SHA1: 65a74f1a5ba7dddcf3de149cb3f4730416092bf4 SHA256: e3389d5d5a418e16c2c7eeefb5812f7c2c38f79d8e7e66ef31bbd0c4d2d296b2 SHA512: 2183620bb00de112d67a830a13f1bc22883ffb4534cb66faefe05d7a4494397506045a4eb4cb2d89a14f57bc89d11a860ea76255d7c9a30156adbc507841231e Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17957 Filename: ./0.11.0/libzenohc_0.11.0_armhf.deb Size: 4476988 MD5sum: 73afe304147a324c03174a9a81adc1f3 SHA1: d50d07f67399165e0c5a8796876caf2649441132 SHA256: 83e4bbb7a501c9d2c608590982f26e31fab6b0888c5b861e36910f85ed96a6f4 SHA512: 07921b85ce9f949c9c79a4f9f69eaafb40f092d2f8e8baf26b5b8451fa5502e7f82fed14a008a889f40f6ee1156c71fe7a83384fd919fe99efff9a0824e2d6d5 Homepage: http://zenoh.io Description: The Zenoh C API . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # C API . This repository provides a C binding based on the main [Zenoh implementation written in Rust](https://github.com/eclipse-zenoh/zenoh). . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in maintaining compatibility between the various git repositories in the Zenoh project. . 1. Make sure that [Rust](https://www.rust-lang.org) is available on your platform. Please check [here](https://www.rust-lang.org/tools/install) to learn how to install it. If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash rustup update ``` . 2. Clone the [source] with `git`: . ```bash git clone https://github.com/eclipse-zenoh/zenoh-c.git ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build: . Good CMake practice is to perform build outside of source directory, leaving source tree untouched. The examples below demonstrates this mode of building. On the other hand VScode by default creates build directory named 'build' inside source tree. In this case build script slightly changes its behavior. See more about it in section 'VScode'. . By default build configuration is set to `Release`, it's not necessary to add `-DCMAKE_BUILD_TYPE=Release` option on configuration step. But if your platform uses multi-config generator by default (this is the case on Windows), you may need to add option `--config Release` on build step. See more in CMake [build-configurations] documentation. Option`--config Release` is skipped in further examples for brewity. It's actually necessary for [Visual Studio generators] only. For [Ninja Multi-Config] the build script is able to select `Release` as the default configuration. . ```bash mkdir -p build && cd build cmake ../zenoh-c cmake --build . --config Release ``` . The generator to use is selected with option `-G`. If Ninja is installed on your system, adding `-GNinja` to `cmake` command can greatly speed up the build time: . ```bash cmake ../zenoh-c -GNinja cmake --build . ``` . [build-configurations]: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations [Visual Studio generators]: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id14 [Ninja Multi-Config]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html . 4. Install: . To install zenoh-c library into system just build target `install`. You need root privileges to do it, as the default install location is `/usr/local`. . ```bash cmake --build . --target install ``` . If you want to install zenoh-c libraries locally, you can set the installation directory with `CMAKE_INSTALL_PREFIX` . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local cmake --build . --target install ``` . By default only dynamic library is installed. Set `ZENOHC_INSTALL_STATIC_LIBRARY` variable to true to install static library also: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DZENOHC_INSTALL_STATIC_LIBRARY=TRUE cmake --build . --target install ``` . The result of installation is the header files in `include` directory, the library files in `lib` directory and cmake package configuration files for package `zenohc` in `lib/cmake` directory. The library later can be loaded with CMake command `find_package(zenohc)`. Add dependency in CMakeLists.txt on target . - `zenohc::shared` for linking dynamic library - `zenohc::static` for linking static library - `zenohc::lib` for linking static or dynamic library depending on boolean variable `ZENOHC_LIB_STATIC` . For `Debug` configuration the library package `zenohc_debug` is installed side-by-side with release `zenohc` library. Suffix `d` is added to names of library files (libzenohc**d**.so). . 5. VScode . When zenoh-c project is opened in VSCode the build directory is set to `build` inside source tree (this is default behavior of Microsoft [CMake Tools]). The project build script detects this situation. In this case it places build files in `target` directory and `Cargo.toml` file (which is generated from `Cargo.toml.in`) into the root of source tree, as the rust developers used to and as the rust build tools expects by default. This behavior also can be explicitly enabled by setting `ZENOHC_BUILD_IN_SOURCE_TREE` variable to `TRUE`. . [CMake Tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools . ## Building the Examples . The examples can be built in two ways. One is to select `examples` as a build target of zenoh-c project (assuming here that the current directory is side-by-side with zenoh-c directory): . ```bash cmake ../zenoh-c cmake --build . --target examples ``` . You may also use `--target ` if you wish to only build a specific example. . All build artifacts will be in the `target/release/examples` directory in this case. . The second way is to directly build `examples` as a root project: . ```bash cmake ../zenoh-c/examples cmake --build . ``` . In this case, the examples executables will be built in the current directory. . As a root project the `examples` project links `zenoh-c` with CMake's [add_subdirectory] command by default. There are also other ways to link `zenoh-c` - with [find_package] or [FetchContent]: . [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [find_package]: https://cmake.org/cmake/help/latest/command/find_package.html [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html . Link with `zenoh-c` installed into default location in the system (with [find_package]): . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE ``` . Link with `zenoh-c` installed in `~/.local` directory: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=PACKAGE -DCMAKE_INSTALL_PREFIX=~/.local ``` . Download specific `zenoh-c` version from git with [FetchContent]: . ```bash cmake ../zenoh-c/examples -DZENOHC_SOURCE=GIT_URL -DZENOHC_GIT_TAG=0.11.0-rc ``` . See also `configure_include_project` function in [helpers.cmake] for more information . [helpers.cmake]: cmake/helpers.cmake . ## Running the Examples . ### Basic Pub/Sub Example . ```bash ./target/release/examples/z_sub ``` . ```bash ./target/release/examples/z_pub ``` . ### Queryable and Query Example . ```bash ./target/release/examples/z_queryable ``` . ```bash ./target/release/examples/z_get ``` . ### Running the Throughput Examples . ```bash ./target/release/examples/z_sub_thr ``` . ```bash ./target/release/examples/z_pub_thr ``` . ## API conventions . Most of the types exposed by the `zenoh-c` API are types for which destruction is necessary. To help you spot these types, we name them with the convention that any destructible type must start by `z_owned`. . For maximum performance, we try to make as few copies as possible. Sometimes, this implies moving data that you `z_owned`. Any function that takes a non-const pointer to a `z_owned` type will perform its destruction. To make this pattern more obvious, we encourage you to use the `z_move` macro instead of a simple `&` to create these pointers. Rest assured that all `z_owned` types are double-free safe, and that you may check whether any `z_owned_X_t` typed value is still valid by using `z_X_check(&val)`, or the `z_check(val)` macro if you're using C11. . We hope this convention will help you streamline your memory-safe usage of zenoh, as following it should make looking for leaks trivial: simply search for paths where a value of a `z_owned` type hasn't been passed to a function using `z_move`. . Functions that simply need to borrow your data will instead take values of the associated `z_X_t` type. You may construct them using `z_X_loan(&val)` (or the `z_loan(val)` generic macro with C11). . Note that some `z_X_t` typed values can be constructed without needing to `z_borrow` their owned variants. This allows you to reduce the amount of copies realized in your program. . The examples have been written with C11 in mind, using the conventions we encourage you to follow. . Finally, we strongly advise that you refrain from using structure field that starts with `_`: . - We try to maintain a common API between `zenoh-c` and [`zenoh-pico`](https://github.com/eclipse-zenoh/zenoh-pico), such that porting code from one to the other is, ideally, trivial. However, some types must have distinct representations in either library, meaning that using these representations explicitly will get you in trouble when porting. - We reserve the right to change the memory layout of any type which has `_`-prefixed fields, so trying to use them might cause your code to break on updates. . ## Logging . By default, zenoh-c enables Zenoh's logging library upon using the `z_open` or `z_scout` functions. This behavior can be disabled by adding `-DDISABLE_LOGGER_AUTOINIT:bool=true` to the `cmake` configuration command. The logger may then be manually re-enabled with the `zc_init_logger` function. . ## Cross-Compilation . The following alternative options have been introduced to facilitate cross-compilation. > :warning: **WARNING** :warning: : Perhaps additional efforts are necessary, that will depend of your environment. . - `-DZENOHC_CARGO_CHANNEL="+nightly"|"+beta"|"+stable"`: refers to a specific rust toolchain release [[rust-channels](https://rust-lang.github.io/rustup/concepts/channels.html)] - `-DZENOHC_CARGO_FLAGS`: several optional flags can be used for compilation. [[cargo flags](https://doc.rust-lang.org/cargo/commands/cargo-build.html)] - `-DZENOHC_CUSTOM_TARGET`: specifies a crosscompilation target. Currently rust support several Tire-1, Tire-2 and Tire-3 targets [[targets](https://doc.rust-lang.org/nightly/rustc/platform-support.html)]. But keep in mind that zenoh-c only have support for following targets: `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-gnu`, `arm-unknown-linux-gnueabi` . Let's put all together in an example: Assuming you want to crosscompile for aarch64-unknown-linux-gnu. . 1. Install required packages - `sudo apt install gcc-aarch64-linux-gnu` 2. *(Only if you're using `nightly`) - `rustup component add rust-src --toolchain nightly` 3. Compile Zenoh-C. Assume that it's in `zenoh-c` directory. Notice that build in this sample is performed outside of source directory . ```bash export RUSTFLAGS="-Clinker=aarch64-linux-gnu-gcc -Car=aarch64-linux-gnu-ar" mkdir -p build && cd build cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+nightly" -DZENOHC_CARGO_FLAGS="-Zbuild-std=std,panic_abort" -DZENOHC_CUSTOM_TARGET="aarch64-unknown-linux-gnu" -DCMAKE_INSTALL_PREFIX=../aarch64/stage cmake --build . --target install ``` . Additionally you can use `RUSTFLAGS` environment variable for lead the compilation. . If all goes right the building files will be located at: `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` and release files will be located at `/path/to/zenoh-c/target/aarch64-unknown-linux-gnu/release` . ## Rust Version . The Rust version we use is defined in [rust-toolchain.toml](rust-toolchain.toml), which is `1.72.0`. There might be some memory mapping issue if you use the later version. . You can also specify the Rust version. . ```bash cmake ../zenoh-c -DZENOHC_CARGO_CHANNEL="+1.72.0" ``` . ## Zenoh features support (enabling/disabling protocols, etc) . It's necessary sometimes to build zenoh-c library with set of features different from default. For example: enable TCP and UDP only. This can be done by changing `ZENOHC_CARGO_FLAGS` parameter for cmake (notice ";" instead of space due to cmake peculiarities) . Available features can be found in Zenoh [Cargo.toml](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/Cargo.toml) . ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=zenoh/transport_tcp,zenoh/transport_udp" ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: zenoh-backend-filesystem Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21952 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-filesystem_0.11.0_amd64.deb Size: 4690804 MD5sum: a71a7bffcce9a605bd1d8bf503ab548b SHA1: f46f645fb3c51f78ca7738d40929e0f763478c03 SHA256: 12853f542d62453fa2a939d4f3297a921a80a3d3dd32272f9e79307afe4379dd SHA512: 84bfa1caf0e50a777cac6192456ec71fe9d87c5af80dfeb75e6c28d57b0590f855e710c4c1f9bd9a1bb082129bdf64dd56986ffeb114b6a49e5f433430e4f1bb Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19689 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-filesystem_0.11.0_arm64.deb Size: 4205396 MD5sum: 2ad2a3a1098bdcfa86b6818684fb1f09 SHA1: 6b66a357e501d747b2cd56d6d36f9c2e91207c93 SHA256: 2e2d272e3e259637eb215f49187488e39b3957e488cb2c250124d99df0f3a0e3 SHA512: d8f311a994b9645a7855fbe75aae3f0934658161a379e8d7e56406edeb52eac4847c10ba37b8411ca9354423bccd92d181652ec7a47308854259d73861a32467 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16553 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-filesystem_0.11.0_armel.deb Size: 3912016 MD5sum: 4bc64261e284af2117a6c7175beb5ef6 SHA1: 0a927781f473ad0e8c68838b7dcd535d2e7f52c7 SHA256: 1c23aef2b3fc21701039e58b08636a7192925fe6a7971075b8c413506606eedf SHA512: 3aa52fe9cf7efc72de404b1e5f8ef3ff8b4fe869165b86d04102665da63bf88a6d74947f642f79484e1dfc0e7f062d6d3004ad4edd7607362e77e50d1e676496 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-filesystem Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14817 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-filesystem_0.11.0_armhf.deb Size: 4009652 MD5sum: 1860b7e7569541ebbdcc8e74e4fecad3 SHA1: 3fb30924d85f211c6a9d5b86aa4e9d6ac83be973 SHA256: 0c7dde8cb35bf5241f9b160b86c181773b80adfa1ebf606621b2adbc53f13f04 SHA512: d64325023e83370b98a055e23c9f321c5d092fa41d0e79d5d445834fd5634f8606e8a8cc74ab4aa2262a96465adb3c6fdbae2bad076cd803c7614b7dac950f58 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-filesystem/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # File system backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. . . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storage-manager" plugin: storage_manager: { volumes: { // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) fs: {}, }, storages: { // configuration of a "demo" storage using the "fs" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to file path // this argument is optional. strip_prefix: "demo/example", volume: { id: "fs", // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) dir: "example" } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - Add the "demo" storage using the "fs" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . . ------------------------------- ## Configuration ### Extra configuration for filesystem-backed volumes . Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. . ------------------------------- ### Storage-level configuration for filesystem-backed volumes . Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): - `dir` (**required**, string) : The directory that will be used to store data. . - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. . - `on_closure` (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - `"do_nothing"`: the storage's directory remains untouched (this is the default behaviour) - `"delete_all"`: the storage's directory is deleted with all its content. . - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. . - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) is returned with the description set to the mime-type. - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with APP_OCTET_STREAM encoding is returned. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to file system Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/`, where: * `${ZENOH_BACKEND_FS_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_fs` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to a file within the storage's directory where: * the file path will be `${ZENOH_BACKEND_FS_ROOT}//`, where `` will be the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * the content of the file will be the value written as a RawValue. I.e. the same bytes buffer that has been transported by zenoh. For UTF-8 compatible formats (StringUTF8, JSon, Integer, Float...) it means the file will be readable as a text format. * the encoding and the timestamp of the key/value will be stored in a RocksDB database stored in the storage directory. . ### Behaviour on deletion . On deletion of a key, the corresponding file is removed. An entry with deletion timestamp is inserted in the RocksDB database (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the RocksDB database from entries with old timestamps that don't have a corresponding existing file. . ### Behaviour on GET . On GET operations, the storage searches for matching and existing files, and return their raw content as a reply. For each, the encoding and timestamp are retrieved from the RocksDB database. But if no entry is found in the database for a file (e.g. for files created without zenoh), the encoding is deduced from the file's extension (using [mime_guess](https://crates.io/crates/mime_guess)), and the timestamp is deduced from the file's modification time. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-filesystem/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-filesystem` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-filesystem ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-filesystem Package: zenoh-backend-influxdb-v1 Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16488 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-influxdb-v1_0.11.0_amd64.deb Size: 3306936 MD5sum: b1bd0d0ba4ec1bf5c34537a445c85c7d SHA1: d9f83e55d807e460ee61318225a923725bb36de8 SHA256: 7081b77c2edd068e7dc75bf2bbed9ad74d4aad5fde21838541c2fe6f6d779907 SHA512: a2a375f0a5acc06d5ef14df5c2939820fd740ddf5c94229c8006e63c3fbf176981ef06e98acfac5c6992883cdd7c1b3896e2fc285bf875fb4f73ae102165904e Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14965 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-influxdb-v1_0.11.0_arm64.deb Size: 2993072 MD5sum: 78e34ac68d921858d2d28474942a4315 SHA1: 34ab3558b50e6596855f5ea1856574d6db2ae8e2 SHA256: f22bcecc0e23b948766104220aafdf27c175bf1db95782de2448a99d886fb9a8 SHA512: 0a40b7040ffbff0db02acdae759a07da765f24fca14549e4278394a5a3d088c653a6c48349913216a297d41721c82f617fc4c5df8471fd4e54b411a1e7a3b4a1 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12575 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-influxdb-v1_0.11.0_armel.deb Size: 2721732 MD5sum: d20cbeb280aec9aa5d2ba4133bd0a8a4 SHA1: 40fb21c482bec4ebf1034acc634730a03beb3f6f SHA256: 1e7f51da321757d096a263545d439eb8829ed5cef0240134a276bf747b09849e SHA512: a9e11ff93bb5ac54efc767eec3f40f7068cdcf9b4c420474a26368bc989aeab32882ec561596bab4815f4ef5de8023b54e0e4c97545ec5490cf229a28addf011 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v1 Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12494 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-influxdb-v1_0.11.0_armhf.deb Size: 2716244 MD5sum: 4f1c762bd915aa3f74639d7b904bb1f1 SHA1: e0a96c997c217fc2c3bb729855ccb762a6011d7a SHA256: 24bb08c5bf8cb47dd25d68c9231213ecd30aa7fb071cc63a72932e5b18258f48 SHA512: 1cc77995b28272576aee899c965a713147e949159c68753b2aee54bbe4eeb09077c8e85e9a1cad4c2cb213955839e9ebe43bc8ef83ad1a3650e9d2c88691d39a Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v1.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This has full support for Influxdb 1.x and partial support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb" volume (the "zenoh_backend_influxdb" backend library will be loaded at startup) //this should be named influxdb for v1 influxdb: { // URL to the InfluxDB service url: "http://localhost:8086", private: { //For Influxdb v1.x: // If needed: InfluxDB credentials, preferably admin for databases creation and drop //username: "admin", //password: "password" . //For Influxdb v2.x: // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // token: "access token" . } } }, storages: { // configuration of a "demo" storage using the "influxdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb for v1 (exactly the same name as in volumes section) id: "influxdb", // the database/bucket name within InfluxDB db: "zenoh_example", // if the database doesn't exist, create it create_db: false, // strategy on storage closure on_closure: "do_nothing", private: { . //For Influxdb v1.x: //Required: InfluxDB credentials to read-write on the bucket //username: "admin", //password: "password" . //For Influxdb v2.x: //Required //InfluxDB credentials, with read/write privileges for the database //this is a token with either: //a.) Read-Write access to the existing DB named above in the config (case where db/bucket already exists) //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh; //(case where a new db/bucket has to be created) // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb` - Add the "demo" storage using the "influxdb" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . #### admin levelcredentials: . . #### for v1.x - **`"username"`** (optional) : an [InfluxDB admin](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/#admin-users) user name. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. . - **`"password"`** (optional) : the admin user's password. . Both `username` and `password` should be hidden behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . . #### for v2.x . - **`"token"`** (optional) : the admin user's token. It will be used for creation and dropping of databases. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . The `token` should be hidden behind a `private` object, like the "username" and "password" shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** works only for Influxdb 1.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v1` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v1 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19783 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-influxdb-v2_0.11.0_amd64.deb Size: 4113772 MD5sum: 12a43e6e2ccf2f8f2301432b15f5b768 SHA1: 36574378f3e00a793911031be3b1598c58346d19 SHA256: 45f432aedb22b39b16a7ec43efcbf4a1f172a2a3727bbc813155b580440c31db SHA512: fda5e88955d93d6b2cba60fe32d8e741772db623979705d3c45f71cb9b789c46cb161a073979cf07c9b1d7e55d8549b0d8483093f6a42c2b0d1dcc5eb310ba11 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18346 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-influxdb-v2_0.11.0_arm64.deb Size: 3792292 MD5sum: 41ced85811aae301f2d71a0a9fca2861 SHA1: 67c6da04b69afff4aca43d8e9c334cb83090b667 SHA256: 793712e34378e764bc8fffb95aac443c1abdd6f4044a5ef29bb085b25398fefc SHA512: 7999ed551535802778244aee0d3249205689e9aa845dc6909cf1fa23a0c07991e8b88db53262be0e055ef7fe7caa25ed1d41e165562c1909b656c2dc8f5bd781 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15673 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-influxdb-v2_0.11.0_armel.deb Size: 3484980 MD5sum: a5e8009637b8aec8ff8505600677e899 SHA1: 88de45938b2e98bda6ef2a40ad575e01dd72ab06 SHA256: 014b5976b8ee68b53db827c9b0e132c68bc71f171458a44b4a3f92b6a1f2481c SHA512: e41ae6cda7935f4f3386a40458facdfd5b09c0fb12351fa2b4fbfe92c1edfe7ab7e23dfc9af970638f55778d47100970f60867680e95d6b0cd3238cb17cf93b2 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-influxdb-v2 Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15555 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-influxdb-v2_0.11.0_armhf.deb Size: 3488500 MD5sum: 6ec31e3f91608ba303530ca5882bb3d9 SHA1: 15f11c1978f58b53544901930bfc802ad28db762 SHA256: 9bd730ff7ba9e1446ea11599d1ad7438740a2af48bda6c30b1ab65f65c1f8002 SHA512: 74bc87ac9f3e028de30c78340c6161957258a48a49f665d0a530d7ec9b854ef3eda1294bae839586b1105f4ee1ba48842777f4037e5d94f0b144ba0348cdc3cf Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB v2.x . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # InfluxDB backend . In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxdb/) server to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_influxdb2`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . :note: This provides extensive support for InfluxDB 2.x. . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_influxdb2` library file is available in `~/.zenoh/lib`. - You have an InfluxDB service running and listening on `http://localhost:8086` . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { plugins: { // configuration of "storage_manager" plugin: storage_manager: { volumes: { // configuration of a "influxdb2" volume (the "zenoh_backend_influxdb2" backend library will be loaded at startup) //this should be named influxdb2 for v2 influxdb2: { // URL to the InfluxDB service url: "http://localhost:8086/api/v2/", private: { // If needed: InfluxDB credentials, preferably ALL-ACCESS for databases creation and drop //if not ALL-ACCESS then atleast with authorization to create/delete buckets //Note: this should not be left empty for the plugin to work; if you have no admin creds, you can copy the user creds instead // org_id: "organization ID", // token: "admin access token" } } }, storages: { // configuration of a "demo" storage using the "influxdb2" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" // this option is optional strip_prefix: "demo/example", volume: { //this will be influxdb2 for v2 (exactly the same name as in volumes section) id: "influxdb2", // the database name within InfluxDB (not the db ID) db: "zenoh_example", // if the database doesn't exist, create it create_db: true, // strategy on storage closure on_closure: "drop_db", private: { //required // If needed: InfluxDB credentials, with read/write privileges for the database //this will be the same as for admin // org_id: "organization ID", //this is any token with either: //a.) Read-Write access to the existing DB mentioned above in the config //b.) Read-write access to ALL buckets in the organization so it can access the new bucket created by zenoh // token: "user access token" } } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on http://localhost:8086: `curl -X PUT -H 'content-type:application/json' -d '{url:"http://localhost:8086/api/v2"}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/influxdb2` - Add the "demo" storage using the "influxdb2" volume: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",volume:{id:"influxdb2",db:"zenoh_example",create_db:true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put some values at different time intervals curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-2" http://localhost:8000/demo/example/test curl -X PUT -d "TEST-3" http://localhost:8000/demo/example/test . # Retrive them as a time serie where '_time=[..]' means "infinite time range" curl -g 'http://localhost:8000/demo/example/test?_time=[..]' ``` . . ------------------------------- ## Volume configuration InfluxDB-backed volumes need some configuration to work: . - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` . - **`"org_id"`** (optional) : an [InfluxDB organizations](https://docs.influxdata.com/influxdb/cloud/admin/organizations/) organization ID. . - **`"token"`** (optional) : the admin user's token. It will be used for creation of databases, granting read/write privileges of databases mapped to storages and dropping of databases and measurements. In Influxdb2.x, you can use an ALL ACCESS token for this (https://docs.influxdata.com/influxdb/cloud/admin/tokens/#all-access-token) . Both `org_id` and `token` should be hidden behind a behind a `private` object, as shown in the example [above](#setup-via-a-json5-configuration-file). In general, if you wish for a part of the configuration to be hidden when configuration is queried, you should hide it behind a `private` object. . ------------------------------- ## Volume-specific storage configuration Storages relying on a `influxdb2` backed volume may have additional configuration through the `volume` section: - **`"db"`** (optional, string) : the InfluxDB database name the storage will map into. If not specified, a random name will be generated, and the corresponding database will be created (even if `"create_db"` is not set). . - **`"create_db"`** (optional, boolean) : create the InfluxDB database if not already existing. By default the database is not created, unless `"db"` property is not specified. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) - `"drop_db"`: the database is dropped (i.e. removed) - `"drop_series"`: all the series (measurements) are dropped and the database remains empty. This is currently not supported in v2. . - **`"org_id"`** (optional, string) :the user's organization. It should be same as the admin's organization. . - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. . ------------------------------- ## **Behaviour of the backend** . ### Mapping to InfluxDB concepts Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - `"timestamp"` field: the original zenoh timestamp - `"encoding"` field: the value's encoding flag - `"base64"` field: a boolean indicating if the value is encoded in base64 - `"value"`field: the value as a string, possibly encoded in base64 for binary values. . ### Behaviour on deletion On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. . ### Behaviour on GET On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadmap/tree/main/rfcs/ALL/Selectors). . :note: Right now, wild chunks like * and ** do not work for Influxdb 2.x. This is due to lack of support in Influxdb 2.x API for our approach. . Examples of selectors: ```bash # get the complete time-series /demo/example/**?_time=[..] . # get points within a fixed date interval /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] . # get points within a relative date interval /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` . See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format . . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-influxdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-influxdb-v2` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-influxdb-v2 ``` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. . ### Example with a downloaded version: ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` . Then build library only for the v2 backend, you have to specify it in the build command: ```bash $ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` You can build both the versions as well: ```bash $ cargo build --release --all-targets ``` . ======= ### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) . And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.72.0 ``` . And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: ```bash $ cargo update -p zenoh --precise 9f7a37ee ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-influxdb Package: zenoh-backend-rocksdb Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21709 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-rocksdb_0.11.0_amd64.deb Size: 4649840 MD5sum: bb75d527995c3c1c526a5b0689ad68d1 SHA1: 5dd94c0928f1cfe5f344f33abb44e5757f9d723a SHA256: 088c28e59831ab7e5bb769a36dbf421ee9c010901426460c000b7c41d19b7e15 SHA512: 915d6dbd611994058e6b14c5b9f72f5c7764e61df609a347b18a90de6cfb912327ae9766527576ff66b9b6676ee57c029a67dec8a0ccabb3522c00f9f50d337e Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19334 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-rocksdb_0.11.0_arm64.deb Size: 4151028 MD5sum: 47800cf83af25f0bc504f577ba2e7f09 SHA1: f10a2edf89f91d97d442266392b3e0ee892a1e37 SHA256: d313aecc08577ae22f779040f0653b05ccf41aeff17cc8861d01e0b5955b82aa SHA512: 2bfc4669e5ace52f100538e223686fc3247fe79e3eb58cd89b1b56d49cf4425176e5fbed659c27d96198719bf7d5e493fdbf997eaacf61e1e14eb3a054509688 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16345 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-rocksdb_0.11.0_armel.deb Size: 3872252 MD5sum: de8225eaac71034ada27a382d2c3d424 SHA1: 5820bc38e97a97fccced60799121b8c9fa3a7d35 SHA256: 445eab9e4994940a2ffcca6ce7299c51e690d3d33890ba429d67793ade1f63e7 SHA512: 57832bca3544daa6604c3f7e40dc23ce565f13acacb926cdedbf1fe0e98c56a9cdcd04ddb415383f2bb984c571036e8144a9e5c0517f30b39f62683e426bae46 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-rocksdb Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14568 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-rocksdb_0.11.0_armhf.deb Size: 3974220 MD5sum: b65e0fc1dd19cdf2b8a4123bfc7a4eeb SHA1: 346e4ef37062702ad9da0b6259ce29bd769e5c83 SHA256: b2bacd4c3fad71775ece1ab85e9621487cf1300916b9d8f4d1a9b2be9a653439 SHA512: 499ec38f73e4e42d44990d190d8dad8bd305475756019553cfeff0efcd5e63fac4ad1dab22d86275a271779623d114d909b981dd5aed321a1f2b25aa2101b164 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB . [![CI](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-backend-rocksdb/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # RocksDB backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](http://zenoh.io/docs/manual/backends/) for more details. . This backend relies on [RocksDB](https://rocksdb.org/) to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_rocksdb`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_rocksdb` library file is available in `~/.zenoh/lib`. - Declare the `ZENOH_BACKEND_ROCKSDB_ROOT` environment variable to the directory where you want the RocksDB databases to be stored. If you don't declare it, the `~/.zenoh/zenoh_backend_rocksdb` directory will be used. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { // configuration of "storages" plugin: storage_manager: { volumes: { // configuration of a "rocksdb" volume (the "zenoh_backend_rocksdb" backend library will be loaded at startup) rocksdb: {} }, storages: { // configuration of a "demo" storage using the "rocksdb" volume demo: { // the key expression this storage will subscribes to key_expr: "demo/example/**", // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "demo/example", volume: { id: "rocksdb", // the RocksDB database will be stored in this directory (relative to ${ZENOH_BACKEND_ROCKSDB_ROOT}) dir: "example", // create the RocksDB database if not already existing create_db: true } } } }, // Optionally, add the REST plugin rest: { http_port: 8000 } } } ``` - Run the zenoh router with: `zenohd -c zenoh.json5` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router, with write permissions to its admin space: `zenohd --adminspace-permissions rw` - Add the "rocksdb" backend (the "zenoh_backend_rocksdb" library will be loaded): `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/rocksdb` - Add the "demo" storage using the "rocksdb" backend: `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example",volume: {id: "rocksdb",dir: "example",create_db: true}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: ```bash # Put values that will be stored in the RocksDB database curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 curl -X PUT -d "B" http://localhost:8000/demo/example/a/b . # Retrive the values curl http://localhost:8000/demo/example/** ``` . ------------------------------- ## Volume-specific storage configuration Storages relying on a RocksDB-backed volume must specify some additional configuration as shown [above](#setup-via-a-json5-configuration-file): - **`"dir"`** (**required**, string) : The name of directory where the RocksDB database is stored. The absolute path will be `${ZENOH_BACKEND_ROCKSDB_ROOT}/`. . - **`"create_db"`** (optional, boolean) : create the RocksDB database if not already existing. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"read_only"`** (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't put anything in RocksDB database. Not set by default. *(the value doesn't matter, only the property existence is checked)* . - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 2 options: - *unset*: the database remains untouched (this is the default behaviour) - `"destroy_db"`: the database is destroyed (i.e. removed) . ------------------------------- ## **Behaviour of the backend** . ### Mapping to RocksDB database Each **storage** will map to a RocksDB database stored in directory: `${ZENOH_BACKEND_ROCKSDB_ROOT}/`, where: * `${ZENOH_BACKEND_ROCKSDB_ROOT}` is an environment variable that could be specified before zenoh router startup. If this variable is not specified `${ZENOH_HOME}/zenoh_backend_rocksdb` will be used (where the default value of `${ZENOH_HOME}` is `~/.zenoh`). * `` is the `"dir"` property specified at storage creation. Each zenoh **key/value** put into the storage will map to 2 **key/values** in the database: * For both, the database key is the zenoh key, stripped from the `"strip_prefix"` property specified at storage creation. * In the `"default"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with the zenoh encoded value as a value. * In the `"data_info"` [Column Family](https://github.com/facebook/rocksdb/wiki/Column-Families) the key is put with a bytes buffer encoded in this order: - the Timestamp encoded as: 8 bytes for the time + 16 bytes for the HLC ID - a "is deleted" flag encoded as a boolean on 1 byte - the encoding prefix flag encoded as a ZInt (variable length) - the encoding suffix encoded as a String (string length as a ZInt + string bytes without ending `\0`) . ### Behaviour on deletion On deletion of a key, the corresponding key is removed from the `"default"` Column Family. An entry with the "deletion" flag set to true and the deletion timestamp is inserted in the `"data-info"` Column Family (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). At regular interval, a task cleans-up the `"data-info"` Column Family from entries with old timestamps and the "deletion" flag set to true . ### Behaviour on GET On GET operations: * if the selector is a unique key (i.e. not containing any `'*'`): the value and its encoding and timestamp for the corresponding key are directly retrieved from the 2 Column Families using `get` RocksDB operation. * if the selector is a key expression: the storage searches for matching keys, leveraging RocksDB's [Prefix Seek](https://github.com/facebook/rocksdb/wiki/Prefix-Seek) if possible to minimize the number of entries to check. . ------------------------------- ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-backend-rocksdb/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-rocksdb` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list > /dev/null sudo apt update sudo apt install zenoh-backend-rocksdb ``` . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Clang](https://clang.llvm.org/) and [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-rocksdb Package: zenoh-backend-s3 Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26353 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-s3_0.11.0_amd64.deb Size: 5212504 MD5sum: 0b926d59ae23ece2709bf8e29a6418bc SHA1: ebba2d31fb3a93fbf8547e67700736da387655b8 SHA256: 43212deca5d1d342a8a927b5eed5cd08a7c9da3c598ab53388dc6f924687dc50 SHA512: 0fbc74c6e2c46f2de7d2c3a89c99c95d658e0e34100ababc109b5f43fa90d562b758d50ccfce334ac1ff775acb7fb39aad709230dd6402455d257a97bb3f88be Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25050 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-s3_0.11.0_arm64.deb Size: 4881600 MD5sum: 348e39fdbcf0efb90ba9c370a2e99607 SHA1: a7fe2f7f973673897e9cfcce8942b41f1400f431 SHA256: 929ad921fc22edfdc6e428da67777e88bd07b4c3bde24bafa92fbfa2f202ead7 SHA512: bae8fe305733204cf4caa840258bcdd610c496011ca7c285311652ad945657858506f3f9b5dbb2a00e70300429a88802c9cb3a61eb502139ac5bf23717761660 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 23424 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-s3_0.11.0_armel.deb Size: 4738356 MD5sum: 5a054a4ebb7c3331f23ab6cfa817dd51 SHA1: 99a468217dafa0bedef9f0a9d5f18db48302e76c SHA256: 1724cb2bef978e26766e88fc22ef1f65e248ff6ccaffeb28439adb379d559171 SHA512: e56283bc9bd2bc13b0a0f77cf87623b7d9b8480a8eceab2c5bd3f49899e909fe6c1ac8040cfee84b1fd8c01d5ac06ab0baff21f421354308afc65b2fe675f399 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-backend-s3 Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 23204 Depends: zenoh-plugin-storage-manager (=0.11.0) Filename: ./0.11.0/zenoh-backend-s3_0.11.0_armhf.deb Size: 4789056 MD5sum: 4de9c27e5673af019cd3655acf561d8b SHA1: 74e2c058944d6c66034389a941cff8e293f23323 SHA256: 66c341cab57cb74d7717a2067530b892ed8a29ca3c1f977e02ab43d26074779c SHA512: e8aa72d396fa768b9813a67d814234054d4a892beb2fca967421b017f66af8fec8cdcb0e45bfd0d5ede235820fe08ec0eb909bd9c5bb2ebeeac5938c5df608f6 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/vSDSpqnbkm) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . # S3 backend . In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the keys/values publications made via zenoh and return them on queries. See the [zenoh documentation](https://zenoh.io/docs/manual/plugin-storage-manager/#backends-and-volumes) for more details. . This backend relies on [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) to implement the storages. It is also compatible to work with [MinIO](https://min.io/) object storage. . Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`libzenoh_backend_s3`**. . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . --- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_backend_s3` library file is available in `~/.zenoh/lib`. Alternatively we can set a symlink to the library, for instance by running: . ``` ln -s ~/zenoh-backend-s3/target/release/libzenoh_backend_s3.dylib ~/.zenoh/lib/libzenoh_backend_s3.dylib ``` . - You have an S3 instance running, this could be an AmazonS3 instance or a MinIO instance. . You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API (see https://zenoh.io/docs/manual/plugin-storage-manager/). . **Setting up a MinIO instance** . In order to run the examples of usage from the following section, it is convenient to launch a MinIO instance. To launch MinIO on a Docker container you first, install MinIO with . ``` docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data quay.io/minio/minio server data --console-address ':9090' ``` . If successful, then the console can be accessed on http://localhost:9090. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing: . ```json5 { plugins: { // Configuration of "storage_manager" plugin: storage_manager: { volumes: { s3: { // AWS region to which connect (see https://docs.aws.amazon.com/general/latest/gr/s3.html). // This field is mandatory if you are going to communicate with an AWS S3 server and // optional in case you are working with a MinIO S3 server. region: "eu-west-1", . // Endpoint where the S3 server is located. // This parameter allows you to specify a custom endpoint when working with a MinIO S3 // server. // This field is mandatory if you are working with a MinIO server and optional in case // you are working with an AWS S3 server as long as you specified the region, in which // case the endpoint will be resolved automatically. url: "https://s3.eu-west-1.amazonaws.com", . // Optional TLS specific parameters to enable HTTPS with MinIO. Configuration shared by // all the associated storages. // tls: { // private: { // // Certificate authority to authenticate the server. // root_ca_certificate_file: "/home/user/certificates/minio/ca.pem", // // // Alternatively you can inline your certificate encoded with base 64: // root_ca_certificate_base64: "" // } //}, }, }, storages: { // Configuration of a "demo" storage using the S3 volume. Each storage is associated to a // single S3 bucket. s3_storage: { // The key expression this storage will subscribes to key_expr: "s3/example/*", . // this prefix will be stripped from the received key when converting to database key. // i.e.: "demo/example/a/b" will be stored as "a/b" strip_prefix: "s3/example", . volume: { // Id of the volume this storage is associated to id: "s3", . // Bucket to which this storage is associated to bucket: "zenoh-bucket", . // The storage attempts to create the bucket, but if the bucket already exists and is // owned by you, then with 'reuse_bucket' you can associate that preexisting bucket to // the storage, otherwise it will fail. reuse_bucket: true, . // If the storage is read only, it will only handle GET requests read_only: false, . // strategy on storage closure, either `destroy_bucket` or `do_nothing` on_closure: "destroy_bucket", . private: { // Credentials for interacting with the S3 bucket access_key: "SARASAFODNN7EXAMPLE", secret_key: "asADasWdKALsI/ASDP22NG/pWokSSLqEXAMPLEKEY", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: ``` zenohd -c zenoh.json5 ``` . **Volume configuration when working with AWS S3 storage** . When working with the AWS S3 storage, the region must be specified following the region names indicated in the [Amazon Simple Storage Service endpoints and quotas ](https://docs.aws.amazon.com/general/latest/gr/s3.html) documentation. The url of the endpoint is not required as the internal endpoint resolver will automatically find which one is the endpoint associated to the region specified. . All the storages associated to the volume will use the same region. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { // AWS region to which connect region: "eu-west-1", } }, ... } ``` . **Volume configuration when working with MinIO** . Inversely, when working with a MinIO S3 storage, then we need to specify the endpoint of the storage rather than the region, which will be ignored by the MinIO server. We can save ourselves to specify the region in that case. . The volumes section on the config file will look like: . ``` storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: ``` cargo run --bin=zenohd ``` - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): ``` curl -X PUT -H 'content-type:application/json' -d '{url: "http://localhost:9000", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/s3 ``` - Add the "s3_storage" storage using the "s3" backend: ``` curl -X PUT -H 'content-type:application/json' -d '{key_expr:"s3/example/*", strip_prefix:"s3/example", volume: {id: "s3", bucket: "zenoh-bucket", create_bucket: true, region: "eu-west-3", on_closure: "do_nothing", private: {access_key: "AKIAIOSFODNN7EXAMPLE", secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage ``` . ### **Tests using the REST API** . Using `curl` to publish and query keys/values, you can: . ```bash # Put values that will be stored in the S3 storage curl -X PUT -H 'content-type:application/json' -d '{"example_key": "example_value"}' http://0.0.0.0:8000/s3/example/test . # To get the stored object curl -X GET -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the previous object curl -X DELETE -H {} -d '{}' http://0.0.0.0:8000/s3/example/test . # To delete the whole storage and the bucket if configured (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/storages/s3_storage' . # To delete the whole volume (note in order for this test to work, you need to setup adminspace read/write permissions) curl -X DELETE 'http://0.0.0.0:8000/@/router/local/config/plugins/storage_manager/volumes/s3' ``` . ## **Enabling TLS on MinIO** . In order to establish secure communication through HTTPS we need to provide a certificate of the certificate authority that validates the server credentials. . TLS certificates can be generated as explained in the [zenoh documentation using Minica](https://zenoh.io/docs/manual/tls/). When running . ``` minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ``` └── certificates ├── localhost │   ├── cert.pem │   └── key.pem ├── minica-key.pem └── minica.pem ``` . On the config file, we need to specify the `root_ca_certificate_file` as this will allow the s3 plugin to validate the MinIO server keys. Example: . ``` tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio/minica.pem", }, }, ``` . Here, the `root_ca_certificate_file` corresponds to the generated _minica.pem_ file. You can also embed directly the root_ca_certificate by inlining it under the filed `root_ca_certificate_base64`, encoded with base64. . The _cert.pem_ and _key.pem_ files correspond to the public certificate and private key respectively. We need to rename them as _public.crt_ and _private.key_ respectively and store them under the MinIO configuration directory (as specified in the [MinIO documentation](https://min.io/docs/minio/linux/operations/network-encryption.html#enabling-tls)). In case you are using running a docker container as previously shown, then we will need to mount the folder containing the certificates as a volume; supposing we stored our certificates under `${HOME}/minio/certs`, we need to start our container as follows: . ``` docker run -p 9000:9000 -p 9090:9090 --user $(id -u):$(id -g) --name minio -e 'MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE' -e 'MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' -v ${HOME}/minio/data:/data -v ${HOME}/minio/certs:/certs quay.io/minio/minio server data --certs-dir certs --console-address ':9090' ``` . Finally the volume configuration should then look like: . ``` storage_manager: { volumes: { s3: { // Endpoint where the S3 server is located url: "https://localhost:9000", . // Configure TLS specific parameters tls: { private: { root_ca_certificate_file: "/home/user/certificates/minio_certs/minica.pem", }, }, }, }, ``` . _Note: do not forget to modify the endpoint protocol, for instance from `http://localhost:9090` to `https://localhost:9090`_ . --- . ## How to install it . To install the latest release of this backend library, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: . - https://download.eclipse.org/zenoh/zenoh-backend-s3/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download the `.zip` file. Unzip it in the same directory than `zenohd` or to any directory where it can find the backend library (e.g. /usr/lib or ~/.zenoh/lib) . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list, and install the `zenoh-backend-s3` package: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update sudo apt install zenoh-backend-s3 ``` . --- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be > built with the exact same Rust version than `zenohd`. Otherwise, incompatibilities in memory mapping > of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: . ```bash $ zenohd --version zenohd v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) The zenoh router v0.7.0-rc-365-geca888b4-modified built with rustc 1.69.0 (84c898d65 2023-04-16) ``` . Here, `zenohd` has been built with the rustc version `1.69.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.69.0 ``` . And then build the backend with: . ```bash $ cargo build --release --all-targets ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-backend-s3 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-backend-s3 Package: zenoh-bridge-dds Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21780 Depends: libc6 (>= 2.29) Filename: ./0.11.0/zenoh-bridge-dds_0.11.0_amd64.deb Size: 5351852 MD5sum: fda234543bb990a2c275a2e9be617c22 SHA1: 392f65da5005de3fad666e3be6f15f2d9f813642 SHA256: 78e8b7ff0cfd690691195883bfb00e0396d6afcd74d449cc2669587cdcc3ef9b SHA512: 6336b97ab4d64cb99286f169266f1c52e769191d770413e7e03680cdb2d98824fc25d2f74921107225366a71b287eab8c5803eca97996746bb519577117d4024 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19357 Filename: ./0.11.0/zenoh-bridge-dds_0.11.0_arm64.deb Size: 4796084 MD5sum: 0bd1b0500e29e24575fc30c2eafe5489 SHA1: 762f4c6da99e876e766b0ae50f9f1a8ae65a3af4 SHA256: d2e06b5bf68fc5040f8cf58f68f216036d82cbf70f336d68b2603f9aa11b6e2b SHA512: e72b1f81a19c71eb68039dbb20f333830b5939c3b91e126b7b0431929acba7b91a914332c3bc6c2aaaa3f58e4f886d0de416abe315663c5dc98c55a69651619f Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20537 Filename: ./0.11.0/zenoh-bridge-dds_0.11.0_armel.deb Size: 5114492 MD5sum: 0a1afbd4748725ea08e230cfbb15bb5d SHA1: 5086293b5fd12105c47fef6940848d74a49b654a SHA256: ab41ad23a68ab209ad8610d144eb39d245191a9fe94ed065fb56f638036ce969 SHA512: 6974d1333cdd6089d4faad6e0671518dc2a4519f4b2a64544cfc11322122879bbf90ed4447ac3040ef7d84f3f131577081b87093951ee450d335099b5dcf8659 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-dds Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20043 Filename: ./0.11.0/zenoh-bridge-dds_0.11.0_armhf.deb Size: 5166852 MD5sum: 75c55c24c3d00127eba5bddf64f79400 SHA1: 7b8f5cf6456ae166f945b4eb872f8e2f6a62e5e2 SHA256: 359236aa17399e4f080fadf35c7192319096c742ec7f2a4666e0a913a794a715 SHA512: de241da8cce4427895f2c6a018b93126d25320bb78415deae38f7ded3286e87e84f749c8f4afd2133311078d6a47694bb7d9e554d5bea7a209c8bc4ed0b68f98 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-bridge-mqtt Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21399 Depends: libc6 (>= 2.29) Filename: ./0.11.0/zenoh-bridge-mqtt_0.11.0_amd64.deb Size: 5073500 MD5sum: 6394afb4fad4db32b72a9a7c2fd551ce SHA1: ea1c5db2eeb6a57bf998c8a9157b22eb1569b834 SHA256: 08fc509ea7f06ed9bda7d2d1eec1c83e3c11186377fc7b1d0ad90a9d6ddc9009 SHA512: 54df4b21d504576451a4cf32f69dc3701d70ca32e86a94a6cd6ee6eb5795767aa3d0e0b8ad12ed9cb2de641b50ef9ef1b689168a5fb5b096a7a2e812b047b6ef Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18906 Filename: ./0.11.0/zenoh-bridge-mqtt_0.11.0_arm64.deb Size: 4529400 MD5sum: 50906313f90e70ee0da9062833d6b169 SHA1: 6997249c296c7b2f78d27ed33e25b8b79a620202 SHA256: 8d86a523bf63d58015c29224a05323db31fbfa4e97042639c490784619830624 SHA512: b495be6a0650f071e752d75193a4a575a2e0e8f2170d972674c98f12eba75307eb41f4e39a9bac41f2fdfa6440bde9a980ae8dd922b6c2e0e2b40af97c335c98 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20278 Filename: ./0.11.0/zenoh-bridge-mqtt_0.11.0_armel.deb Size: 4866952 MD5sum: 13d2232ef6dfc3f6756f276118f5c7dd SHA1: 486b975d6bc1a84b2f9926dd94d5dee73de2b026 SHA256: 4a09b44f235c8c70bb24ef3bbff7c1d6e2e15f637b16398f3397011f48213838 SHA512: 33beac3ad9d18156de5f530c2da58f223fd99c97a0de88a9994683e203bc05a25501e86a54ac1ebf1b5c1e95e0ad28beab05e6d86eb4f6cc1f819787701b6b51 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20010 Filename: ./0.11.0/zenoh-bridge-mqtt_0.11.0_armhf.deb Size: 4896644 MD5sum: 8b39fa1c26e023a3f9de0d4e9f3de1ca SHA1: 0724abbf2927e7c7b0c350dc24d02cd5291737e7 SHA256: 14f4aa54733faab8732acf94206897af0bd0ec7f5b4cbda2b988951ef0c017e3 SHA512: b0a867c4b0180fe0574a98c352a57a3f8605e931917aff8c2431b840c617501fc182bbcafe5c299acc935ceff2b744f20931bd4a7bc41ede7e97a85798e7d878 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-ros1 Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 22847 Depends: libc6 (>= 2.29) Filename: ./0.11.0/zenoh-bridge-ros1_0.11.0_amd64.deb Size: 5454368 MD5sum: ce6fb618378911b39f529113fd98cf66 SHA1: 8305dbdd7e568980fcb20fe3a0b8761bbfa49bab SHA256: 85a34aa73308e7736f1f69951750bd80fb5fa4052129d57f33b20522a4d49439 SHA512: 458e336ff03042414d58980df1a926c2a23e5bd267fa43d593989ecdc2be20a0f7ae3f3e295f02996dbd537e417fa67e725b75bae3acaac77af430c4f77e7237 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20295 Filename: ./0.11.0/zenoh-bridge-ros1_0.11.0_arm64.deb Size: 4884112 MD5sum: a6ee5e3a07911980824266cb10a39091 SHA1: ff5a447ae63e284b0ae456de3b3dc8a1604561d1 SHA256: 5997487b4e49be703425ef157108451fa6371370214fd08f77bf5f76f4ba9c7f SHA512: 8372ffcc56f30a41d70b57c5f62c05366ce96577064c27eac2fd75a6e69a213aec4c4bf7b547c270199c7599ab3f0126216277e9e17cf559d6437952ad3218b3 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21640 Filename: ./0.11.0/zenoh-bridge-ros1_0.11.0_armel.deb Size: 5248172 MD5sum: 3dc9b166bd7af68cce96ec8f17b44651 SHA1: c39c2b6fd0d4d99fa1fece756ff0b299ac7a3b1b SHA256: b5c8c37eec262ad846494a5fefed855f2bf9a24fb5873435e8200ee37de846b9 SHA512: bd7151aef1bfb19027655c81c182fd9b6ff2cec6c78969b283e2f94dcebed43ef8f3baad51ca20715f53ca0d0cd3701398e12003f05ad44950b445f2c809f4c4 Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros1 Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21325 Filename: ./0.11.0/zenoh-bridge-ros1_0.11.0_armhf.deb Size: 5283544 MD5sum: 0358e1e11a5fdf1afa04a878187bbc35 SHA1: 0a8d8703409a53ac68a411b17ed2204dcbb71a48 SHA256: 910168622b3a287877b4e1c0cb9d876500b461a3f875743e75916540a4318c07 SHA512: f7f641af8def896767adba9e0c16dcfb254af04675361b497f787549c0b9b1b0bb9f24acdb38a733cac0253ee8c18972a772f1a726caf1eccb264f253df864ce Homepage: http://zenoh.io Description: Zenoh bridge for ROS1 Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 22370 Depends: libc6 (>= 2.29) Filename: ./0.11.0/zenoh-bridge-ros2dds_0.11.0_amd64.deb Size: 5473332 MD5sum: b62a75e33fccf55fc059c039f8a2d2d4 SHA1: 635766569fc45304c30364dccb446c509e33c235 SHA256: f85b4385849904b3ee940ed9d2c4d438ffa2d5bbaf37e3963e65a8f28f6b515f SHA512: 60c8dc92f0397550cfb94bec70d037e81cffb3eecc7c1cc2594074bf05206af7599db9467d19783ad9775bfb2150ee81cd5d639aeba802f1850a0a8637cb856c Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19932 Filename: ./0.11.0/zenoh-bridge-ros2dds_0.11.0_arm64.deb Size: 4917808 MD5sum: 5fdcf1fa86518c1cf7a12681b8612ed7 SHA1: ced7f4307648aba0e276a6dd034b384c7d1d2918 SHA256: 2d085d7a457a309100f5cd8f56707ac6c7fafa8014c839a97a1081f5aa8aafd5 SHA512: 6292a1587ea5917ae14b7db5661df7081821bb7589d468adfac7be8e2e2c0a58d4442205fce67e689c32e9d4dd45f5c3dda477253c119badce6bfddb2a6db695 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21134 Filename: ./0.11.0/zenoh-bridge-ros2dds_0.11.0_armel.deb Size: 5246856 MD5sum: 9dff687031ce904a4f5a069304a84a16 SHA1: ee82ff6b89850a54d93bbaf72891cd0bbd2a76b8 SHA256: 7d8b404873693cac2268a322af51a0709acb44b6efda463f6d083ce9d2ecedd7 SHA512: 1622d3a2182b22f11d84db10d2878df51729f7df4dd768d0ca11486569ece6a80e29de8e81515eea6cd148ea213088b060fcc80c3e1f37a344276fb02e703481 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-bridge-ros2dds Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20633 Filename: ./0.11.0/zenoh-bridge-ros2dds_0.11.0_armhf.deb Size: 5302148 MD5sum: 001b0d27fc7328878db89193937346ef SHA1: 9969bd048ab69314b61a4644e515d4bf4f05fffa SHA256: f6c10e572946cb09fc1df1cdb60752e0cdcd69e5fdb4996d03d90284cdfa5fdb SHA512: e4f8269eaf4f152ff2c65b432908767fe189f8c2f11a75957d25e58c465b0b81aad47bad4cb650bb34145da72e4f8cbbd72d2c8cf7af724c30dd54ab27ba7288 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-dds Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14133 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-dds_0.11.0_amd64.deb Size: 2739876 MD5sum: d66a52f74994408ded27ce2f15eb1979 SHA1: 41d8db1887de53b73895d276c4cf04d0cdb2a1d0 SHA256: 81eea0e9aecf148a2720840d86b317590e7783e7db38136630b0898e64c065f0 SHA512: 9512885ead3e01c9c48556a0d3ea85133f6ac8aaec24af457547afd5273e64d751de07449d353e5db313c3a6edc38ef99d0fe599ffd9e2dfccfc199f530cfd61 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12522 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-dds_0.11.0_arm64.deb Size: 2472832 MD5sum: e7251749f868f02073744c0a67dc6295 SHA1: 1ebe1af99a18a0916cef417f323663f8db705ce0 SHA256: d546406e392f856093112b74fd15c80b2f3ca538130fab8d62c1e9702cd53e31 SHA512: 1efdc0f55d5a94a2a02bf776312cad9fe64a11721da2ccd7d2ab978a5955998c2959db75aac50ab20a49ba11a014363dfff6f0b6d87c8cc5fb5752bedc31c715 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9771 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-dds_0.11.0_armel.deb Size: 2249052 MD5sum: 936ad6c3ed962e59e7fee2d449b9ab93 SHA1: 13343837d9efd225efe20ccd09001f0dd61b0230 SHA256: e17f402bc198296747f7b24ec9132c387ac445416f07a8ce1f19d5df43e1a055 SHA512: 93c8faefcc27f315b211f7ccb0336991e0907d7d33507294b5a5a9d3d2805f2c5b65bb0b131b155b81baabf6ab747c687c49e9a25a617f17ccd34222be46eb98 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-dds Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9448 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-dds_0.11.0_armhf.deb Size: 2256252 MD5sum: 7600d11610b7b80cf8508154f70cea50 SHA1: 08793d4a093fd51508becfa2500c1a0facbd138a SHA256: 9498f02fcdcffd4421bda554fa292ebe8140326f24d11ce35ba8c35017848a84 SHA512: c11b0c958d8bfdab4e9b356bf3e2053a3a2f38c108b864a6f4d97abf82dc96294d77e53b605652b93243c148da4c1f63df84b474533af32a1aac8fb055b8f116 Homepage: http://zenoh.io Description: Zenoh plugin for ROS2 and DDS in general . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # DDS plugin and standalone `zenoh-bridge-dds` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background The Data Distribution Service (DDS) is a standard for data-centric publish subscribe. Whilst DDS has been around for quite some time and has a long history of deployments in various industries, it has recently gained quite a bit of attentions thanks to its adoption by the Robotic Operating System (ROS 2) -- where it is used for communication between ROS 2 nodes. . ### ⚠️ On usage with ROS 2 ⚠️ . This plugin is based on the DDS standard, and thus can work with ROS 2 to some extent. . However we strongly advise ROS 2 users to rather try the **new [`zenoh-plugin-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds)** which is dedicated to the support of ROS 2 with DDS. Thanks to a better integration with ROS 2 concepts, this new plugin comes with those benefits: . - Better integration of the **ROS graph** (all ROS topics/services/actions can be seen across bridges) - Better support of **ROS toolings** (ros2 CLI, rviz2...) - Configuration of a **ROS namespace** on the bridge (instead of on each ROS Node) - Services and Action as **Zenoh Queryables** with more efficiency and scalability that RPC over DDS - Even more **compact discovery information** between the bridges (not forwarding all `ros_discovery_info` messages as such) . This Zenoh plugin for DDS will eventually be deprecated for ROS 2 usage. . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-dds`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git $ cd zenoh-plugin-dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . ### Enabling Cyclone DDS Shared Memory Support . Cyclone DDS Shared memory support is provided by the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.1/getting-started/installation/#dependencies). . To build the zenoh bridge for DDS with support for shared memory the `dds_shm` optional feature must be enabled during the build process as follows: - plugin library: ```bash $ cargo build --release -p zenoh-plugin-dds --features dds_shm ``` . - standalone executable binary: ```bash $ cargo build --release -p zenoh-bridge-dds --features dds_shm ``` . **Note:** Iceoryx does not need to be installed to build the bridge when the `dds_shm` feature is enabled. Iceoryx will be automatically downloaded, compiled, and statically linked into the zenoh bridge as part of the cargo build process. . When the zenoh bridge is configured to use DDS shared memory (see [Configuration](#configuration)) the **Iceoryx RouDi daemon (`iox-roudi`)** must be running in order for the bridge to start successfully. If not started the bridge will wait for a period of time for the daemon to become available before timing out and terminating. . When building the zenoh bridge with the `dds_shm` feature enabled the `iox-roudi` daemon is also built for convenience. The daemon can be found under `target/debug|release/build/cyclors-/out/iceoryx-build/bin/iox-roudi`. . See [here](https://cyclonedds.io/docs/cyclonedds/latest/shared_memory/shared_memory.html) for more details of shared memory support in Cyclone DDS. . . ## ROS 2 package :warning: **Please consider using [`zenoh-bridge-ros2dds`](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) which is dedicated to ROS 2.** . If you're a ROS 2 user, you can also build `zenoh-bridge-dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . ## Docker image The **`zenoh-bridge-dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-dds:main` for the main branch version (nightly build) . :warning: **However, notice that it's usage is limited to Docker on Linux and using the `--net host` option.** The cause being that DDS uses UDP multicast and Docker doesn't support UDP multicast between a container and its host (see cases [moby/moby#23659](https://github.com/moby/moby/issues/23659), [moby/libnetwork#2397](https://github.com/moby/libnetwork/issues/2397) or [moby/libnetwork#552](https://github.com/moby/libnetwork/issues/552)). The only known way to make it work is to use the `--net host` option that is [only supported on Linux hosts](https://docs.docker.com/network/host/). . Usage: **`docker run --init --net host eclipse/zenoh-bridge-dds`** It supports the same command line arguments than the `zenoh-bridge-dds` (see below or check with `-h` argument). . ------------------------------- # Usage . The use cases of this Zenoh plugin for DDS are various: - integration of a DDS System with a Zenoh System - communication between DDS System and embeded devices thanks to [zenoh-pico](https://github.com/eclipse-zenoh/zenoh-pico) - bridging between different DDS Systems, across various transports, via a Zenoh infrastructure (i.e. some routers or directly in peer-to-peer between the bridges) - scaling a DDS system up to the Cloud with Zenoh routers - integration with any technology supported by other Zenoh Plugins (MQTT, ROS 2 ...) or Storages technology (InfluxDB, RocksDB) . . ## Configuration . `zenoh-bridge-dds` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-dds` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--group-member-id `** : The bridges are supervising each other via zenoh liveliness tokens. This option allows to set a custom identifier for the bridge, that will be used the liveliness token key (if not specified, the zenoh UUID is used). - **`--rest-http-port `** : set the REST API http port (default: 8000) * DDS-related arguments: - **`-d, --domain `** : The DDS Domain ID. By default set to `0`, or to `"$ROS_DOMAIN_ID"` is this environment variable is defined. - **`--dds-localhost-only`** : If set, the DDS discovery and traffic will occur only on the localhost interface (127.0.0.1). By default set to false, unless the "ROS_LOCALHOST_ONLY=1" environment variable is defined. - **`--dds-enable-shm`** : If set, DDS will be configured to use shared memory. Requires the bridge to be built with the 'dds_shm' feature for this option to valid. By default set to false. - **`-f, --fwd-discovery`** : When set, rather than creating a local route when discovering a local DDS entity, this discovery info is forwarded to the remote plugins/bridges. Those will create the routes, including a replica of the discovered entity. More details [here](#full-support-of-ros-graph-and-topic-lists-via-the-forward-discovery-mode) - **`-s, --scope `** : A string used as prefix to scope DDS traffic when mapped to zenoh keys. - **`-a, --allow `** : A regular expression matching the set of 'partition/topic-name' that must be routed via zenoh. By default, all partitions and topics are allowed. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. Examples of expressions: - `.*/TopicA` will allow only the `TopicA` to be routed, whatever the partition. - `PartitionX/.*` will allow all the topics to be routed, but only on `PartitionX`. - `cmd_vel|rosout` will allow only the topics containing `cmd_vel` or `rosout` in their name or partition name to be routed. - **`--deny `** : A regular expression matching the set of 'partition/topic-name' that must NOT be routed via zenoh. By default, no partitions and no topics are denied. If both 'allow' and 'deny' are set a partition and/or topic will be allowed if it matches only the 'allow' expression. Repeat this option to configure several topic expressions. These expressions are concatenated with '|'. - **`--max-frequency ...`** : specifies a maximum frequency of data routing over zenoh per-topic. The string must have the format `"regex=float"` where: - `"regex"` is a regular expression matching the set of 'partition/topic-name' for which the data (per DDS instance) must be routedat no higher rate than associated max frequency (same syntax than --allow option). - `"float"` is the maximum frequency in Hertz; if publication rate is higher, downsampling will occur when routing. . (usable multiple times) - **`--queries-timeout `**: A duration in seconds (default: 5.0 sec) that will be used as a timeout when the bridge queries any other remote bridge for discovery information and for historical data for TRANSIENT_LOCAL DDS Readers it serves (i.e. if the query to the remote bridge exceed the timeout, some historical samples might be not routed to the Readers, but the route will not be blocked forever). - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. . ## Admin space . The zenoh bridge for DDS exposes an administration space allowing to browse the DDS entities that have been discovered (with their QoS), and the routes that have been established between DDS and zenoh. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-dds` startup using the `--rest-http-port` argument. . Starting from version `0.11.0-rc.2`, the `zenoh-bridge-dds` exposes this administration space with paths prefixed by `@dds/` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@dds//version` : the bridge version - `@dds//config` : the bridge configuration - `@dds//participant//reader//` : a discovered DDS reader on `` - `@dds//participant//writer//` : a discovered DDS reader on `` - `@dds//route/from_dds/` : a route established from a DDS writer to a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)). - `@dds//route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-dds-topics-to-zenoh-resources)).. . For previous versions, see the corresponding version of README.md: [0.10.1-rc](https://github.com/eclipse-zenoh/zenoh-plugin-dds/blob/0.10.1-rc/README.md#admin-space). . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - List all the DDS entities that have been discovered: ```bash curl http://localhost:8000/@dds/*/participant/** ``` - List all established routes: ```bash curl http://localhost:8000/@dds/*/route/** ``` - List all discovered DDS entities and established route for topic `cmd_vel`: ```bash curl http://localhost:8000/@dds/**/cmd_vel ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## Architecture details . The **zenoh bridge for DDS** discovers all DDS Writers and Readers in a DDS system and routes each DDS publication on a topic `T` as a Zenoh publication on key expression `T`. In the other way, assuming a DDS Reader on topic `T` is discovered, it routes each Zenoh publication on key expression `T` as a DDS publication on topic `T`. . The bridge doesn't deserialize the DDS data which are received from DDS Writer as a `SerializedPayload` with the representation defined in §10 of the [DDS-RTPS specification](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF). Therefore, the payload published from any Zenoh application for a DDS Reader served by the bridge must have such format: ``` 0...2...........8...............16..............24..............32 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | representation_identifier | representation_options | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~ ~ ~ ... Bytes of data representation using a format that ... ~ ~ ... depends on the RepresentationIdentifier and options ... ~ ~ ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Where the first 4 bytes (representation_identifier and representation_options) are usually `{0x00, 0x0}` for Big Endian encoding or `{0x00, 0x01}` for Little Endian encoding, and the remaining bytes are the data encoded in CDR. . . In details, whether it's built as a library or as a standalone executable, it does the same things: - in default mode: - it discovers the DDS readers and writers declared by any DDS application, via the standard DDS discovery protocol (that uses UDP multicast) - it creates a mirror DDS writer or reader for each discovered reader or writer (using the same QoS) - if maps the discovered DDS topics and partitions to zenoh keys (see mapping details below) - it forwards user's data from a DDS topic to the corresponding zenoh key, and vice versa - it does not forward to the remote bridge any DDS discovery information . - in "forward discovery" mode - each bridge will forward via zenoh the local DDS discovery data to the remote bridges (in a more compact way than the original DDS discovery traffic) - each bridge receiving DDS discovery data via zenoh will create a replica of the DDS reader or writer, with similar QoS. Those replicas will serve the route to/from zenoh, and will be discovered by the ROS2 nodes. - for ROS 2 systems, each bridge will forward the `ros_discovery_info` data (in a less intensive way than the original publications) to the remote bridges. On reception, the remote bridges will convert the original entities' GIDs into the GIDs of the corresponding replicas, and re-publish on DDS the `ros_discovery_info`. The full ROS graph can then be discovered by the ROS 2 nodes on each host. . . ### _Mapping of DDS topics to zenoh keys_ The mapping between DDS and zenoh is rather straightforward: given a DDS Reader/Writer for topic **`A`** without the partition QoS set, then the equivalent zenoh key will have the same name: **`A`**. If a partition QoS **`P`** is defined, the equivalent zenoh key will be named as **`P/A`**. . Optionally, the bridge can be configured with a **scope** that will be used as a prefix to each zenoh key. That is, for scope **`S`** the equivalent zenoh key will be: - **`S/A`** for a topic **`A`** without partition - **`S/P/A`** for a topic **`A`** and a partition **`P`** . ### _Mapping ROS 2 names to zenoh keys_ The mapping from ROS 2 topics and services name to DDS topics is specified [here](https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts). Notice that ROS 2 does not use the DDS partitions. As a consequence of this mapping and of the DDS to zenoh mapping specified above, here are some examples of mapping from ROS 2 names to zenoh keys: . | ROS2 names | DDS Topics names | zenoh keys (no scope) | zenoh keys (if scope="`myscope`") | | --- | --- | --- | --- | | topic: `/rosout` | `rt/rosout` | `rt/rosout` | `myscope/rt/rosout` | | topic: `/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `rt/turtle1/cmd_vel` | `myscope/rt/turtle1/cmd_vel` | | service: `/turtle1/set_pen` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `rq/turtle1/set_penRequest`
`rr/turtle1/set_penReply` | `myscope/rq/turtle1/set_penRequest`
`myscope/rr/turtle1/set_penReply` | | action: `/turtle1/rotate_absolute` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `rq/turtle1/rotate_absolute/_action/send_goalRequest`
`rr/turtle1/rotate_absolute/_action/send_goalReply`
`rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`rq/turtle1/rotate_absolute/_action/get_resultRequest`
`rr/turtle1/rotate_absolute/_action/get_resultReply`
`rt/turtle1/rotate_absolute/_action/status`
`rt/turtle1/rotate_absolute/_action/feedback` | `myscope/rq/turtle1/rotate_absolute/_action/send_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/send_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/cancel_goalRequest`
`myscope/rr/turtle1/rotate_absolute/_action/cancel_goalReply`
`myscope/rq/turtle1/rotate_absolute/_action/get_resultRequest`
`myscope/rr/turtle1/rotate_absolute/_action/get_resultReply`
`myscope/rt/turtle1/rotate_absolute/_action/status`
`myscope/rt/turtle1/rotate_absolute/_action/feedback` | | all parameters for node `turtlesim`| `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `rq/turtlesim/list_parametersRequest`
`rr/turtlesim/list_parametersReply`
`rq/turtlesim/describe_parametersRequest`
`rr/turtlesim/describe_parametersReply`
`rq/turtlesim/get_parametersRequest`
`rr/turtlesim/get_parametersReply`
`rr/turtlesim/get_parameter_typesReply`
`rq/turtlesim/get_parameter_typesRequest`
`rq/turtlesim/set_parametersRequest`
`rr/turtlesim/set_parametersReply`
`rq/turtlesim/set_parameters_atomicallyRequest`
`rr/turtlesim/set_parameters_atomicallyReply` | `myscope/rq/turtlesim/list_parametersRequest`
`myscope/rr/turtlesim/list_parametersReply`
`myscope/rq/turtlesim/describe_parametersRequest`
`myscope/rr/turtlesim/describe_parametersReply`
`myscope/rq/turtlesim/get_parametersRequest`
`myscope/rr/turtlesim/get_parametersReply`
`myscope/rr/turtlesim/get_parameter_typesReply`
`myscope/rq/turtlesim/get_parameter_typesRequest`
`myscope/rq/turtlesim/set_parametersRequest`
`myscope/rr/turtlesim/set_parametersReply`
`myscope/rq/turtlesim/set_parameters_atomicallyRequest`
`myscope/rr/turtlesim/set_parameters_atomicallyReply` | | specific ROS discovery topic | `ros_discovery_info` | `ros_discovery_info` | `myscope/ros_discovery_info` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-dds Package: zenoh-plugin-mqtt Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14775 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-mqtt_0.11.0_amd64.deb Size: 2940220 MD5sum: 03d9cf0386e5c649d7aa291760c0c991 SHA1: 5ed3831b35796e2bfa4bebd03f8db72ce2bfb20f SHA256: 17bb273b58671d6a91767d27f694d950c4d774aa4c1d4c70cec1ff7b41b9c123 SHA512: 9e2971d6c701bb98562ce93252a89a68480325f538722ec3417db4088904d505a7e5c45b0c4cc7f4092d4881254fba6611539f9ce9ebb4cef9f602fa4cc58899 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13017 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-mqtt_0.11.0_arm64.deb Size: 2618456 MD5sum: 16eda21a287bf48a3ffe9d0098915db9 SHA1: 155c823002edbf0d1adb4318491323d4db76200c SHA256: bed08ee3e209111310c391c060ec0b4ad4b17c4c8d8bc68bcd9c45020757e19a SHA512: 9390dd1a93ddd1ed153e7aae0dbea790447331bd7fc90c1e75f87734dbebf512cc1ab8fae917f5ad7d7fedbd6bfc5a84f172dc240cc8411e022591243c0afb24 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11167 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-mqtt_0.11.0_armel.deb Size: 2430272 MD5sum: 7f984e1861258dba69dc3fc0b1c9fcfc SHA1: e2cf5e9396d8ba7b385b0e554d4f74c06063ac11 SHA256: b2ee68c97634456e4cd6283ebb76452f3f5156987f90792939e9126aeea9caf8 SHA512: 8bfc7e52bdaa038ba3a0f197dee60c6eba063208a9763b8f58d9ae4c581d03608d2a0b8826d644b13ab35e3ea2fe1aa8c269c3f1768653cd3279b12b1ad69fd6 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11078 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-mqtt_0.11.0_armhf.deb Size: 2433892 MD5sum: 0c0c7fa3688a9077a7bff431ccc2e9c4 SHA1: f6c8c98c52a3c27a72bab9e729b8d6cee24697cc SHA256: 02a934800dc946886a77e8776e72f9d2f4eb7996d934f602cb33923f724db50d SHA512: 15a896ff8b83c9c7d17b961f40d879cf6d86f60b04db5ca1c1a94c135493461ee03edaa57960340196d0c135cb191b21f9f20f6b99249cfa28c4e115339b99c9 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-ros1 Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16754 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-ros1_0.11.0_amd64.deb Size: 3360172 MD5sum: 39a8f95c3260f885949d82305bab2efb SHA1: 62944344cf12732d4762cefbcedc6a64ebe9227f SHA256: 94953a7ee9d518bb4f3174199d5824326154f029df2385041b9764426c2f0e27 SHA512: 3a92419e3f0db8755735846be13c4c9e7c7cbf87a10dc845a23862be2cb36fb40456f22baf3a1bd3fb0ee3573c1ffc6e0234f50e400c1ad3a6cab0634bb5beaa Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14922 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-ros1_0.11.0_arm64.deb Size: 3065512 MD5sum: 8853c79b8c70be0f269308d8a0e6bc58 SHA1: e51b3091a4666c64dcc722ae31b1ebe857ee445d SHA256: 077460f6e6b38c07078d4d893bf1ddb2b6900bede273a84389b31fdc87a24cc5 SHA512: f9f9830bcc8006f640e7d6a7bb0875bb10b49e7281db3dc25e1cb31514836a7d27403d1cb42030568ff7e92f1e109897a8c40a3666037975f7380ac090339a26 Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12381 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-ros1_0.11.0_armel.deb Size: 2896692 MD5sum: e5fd90177acc504e66c4f26c557e64d2 SHA1: ae2e4c13d69dca7b7d8ebd334e7fb4bb643819e3 SHA256: bae4e5050ccde49e4e781f441b7cbcc83958da16bfd7a0938f6725a43c4fe934 SHA512: 84ea6686545c7f36cf4bc1f40ce5a28449a40664591eb9f6c29319f6f0d796d74270acc26684590a82553e03e90837208a779849064839dd8d7b3a94af40e4c4 Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros1 Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12206 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-ros1_0.11.0_armhf.deb Size: 2874444 MD5sum: 8ea87a8969aed2ca5d689dc657425639 SHA1: bedb1637b34fefc4d9e04bf8adc5ac2e5e345f0d SHA256: 241f556440b4df17883f13e891f35b4fe7e517d6138bb5b4360840198a3b8adf SHA512: 1e7fc3a1d98dbf606a83f20c9dbc39671802469a16445b95157a4d41af3f465b0ddfafb8c3d7914fbc8ed4558740a469de8fa56a6627bd319b208240cc796f5e Homepage: http://zenoh.io Description: Zenoh plugin for bidging ROS1 . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # ROS1 to Zenoh Bridge plugin . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background ROS1 is a well-known mature platform for building robotic systems. Despite the fact that next generation of ROS - ROS2 is released long time ago, many developers still prefer using ROS1. In order to integrate ROS1 systems to Zenoh infrastructure, [as it was done for DDS/ROS2](https://github.com/eclipse-zenoh/zenoh-plugin-dds), ROS1 to Zenoh Bridge was designed. . ## How to install it . To install the latest release of either the ROS1 plugin for the Zenoh router, either the `zenoh-bridge-ros1` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros1/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros1--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros1--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros1` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros1`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros1`. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . > :warning: **WARNING** :warning: : We failed to build the plugin's tests on the system with 2(1)GB of RAM(swap) as ld ran out of memory, please pay attention to this fact! . In order to build the ROS1 to Zenoh Bridge, you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git $ cd zenoh-plugin-ros1 $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros1` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## Docker image The **`zenoh-bridge-ros1`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros1/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros1:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros1:main` for the main branch version (nightly build) . Usage: **`docker run --init --net host eclipse/zenoh-bridge-ros1`** It supports the same command line arguments than the `zenoh-bridge-ros1` (see below or check with `-h` argument). . ## A quick test with built-in examples . If you want to run examples or tests, you need to install ROS1: ```bash $ sudo apt install -y ros-base ``` . There is a set of example utilities illustarating bridge in operation. Here is a description on how to configure the following schema: ``` _____________________________ ________________________________ | | | | | rosmaster_1 | | rosmaster_2 | | | | | | ros1_publisher -> zenoh-bridge-ros1 -> zenoh -> zenoh-bridge-ros1 -> ros1_subscriber | |___________________________| |______________________________| ``` . ```bash # build the bridge from source cargo build -p zenoh-bridge-ros1 cd target/debug/ # terminal 1: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 # terminal 2: ./zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 # terminal 3: ROS_MASTER_URI=http://localhost:10000 rostopic pub /topic std_msgs/String -r 1 test_message # terminal 4: ROS_MASTER_URI=http://localhost:10001 rostopic echo /topic ``` . Once completed, you will see the following exchange between ROS1 publisher and subscriber: . ## Implementation Currently, ROS1 to Zenoh Bridge is based on [rosrust library fork](https://github.com/ZettaScaleLabs/rosrust). Some limitations are applied due to rosrust's implementation details, and we are re-engineering rosrust to overcome this . ## Limitations - all topic names are bridged as-is - there is a performance impact coming from rosrust . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros1 Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14782 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-ros2dds_0.11.0_amd64.deb Size: 2861688 MD5sum: 626ab90302a14237890b8309d708e73d SHA1: 6ae3e4a628803581d237bc261f6e67976267b74f SHA256: 4bbd9ac6a699c939f33a077049c503d0fd2dfff49ea7195e90ca32c0929fa10a SHA512: 3814f3488e8ebac3ad296a92a168ce2b6926776f3f0b0fda98222409834a118cb26c74352e8feca3eff729782dbbd6670ea7b7fad084782a4b56721bfb9bdc64 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13064 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-ros2dds_0.11.0_arm64.deb Size: 2585736 MD5sum: f642334c28efe4055a598fe65bb3f96f SHA1: a445c70d2cd66a957df6a194a1d7789b136e88b0 SHA256: eabe87733d1a3ae59a9d8964f7ffe61dfa634ca22fb516d71c44f6a7edda88f8 SHA512: 1cd58a5f748658c7609a2083cd4ba7daac4d53a538853d61b19cf98cb6b289751451eccefba344e0c373315f6ae11d737e120c3d3285b7d883d6fc9098efc70a Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10361 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-ros2dds_0.11.0_armel.deb Size: 2377984 MD5sum: 30e06250390e41ce968be7650d47d08d SHA1: 771a5965de1d09bef9d60b7802821a7bcc428859 SHA256: 6693ce48de844484a90087719d259c057e6d062ead0065b186a876048aade3fc SHA512: 75a9c672e4324c25b53748eb2034facb2bfd70b533b4719df91e76dcc5a124d16fef78c2afbf24f889acfe738401a1ed9e6ce55e8a0265fe11bf78d5c4394893 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-ros2dds Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10026 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-ros2dds_0.11.0_armhf.deb Size: 2387332 MD5sum: 30a53e78567c21a3653a261a9c22f7a8 SHA1: 18aad9918d8a0f18d270d7e8189f820c26d6bf15 SHA256: 318c3ff4160e38db73c56012a9116a543a08db41e8524d4807f45f2a99d28357 SHA512: 1b93a74728b7afffa5ab855b64bd496558a6df97f07f2308a5b55247872643c88d8bc2a8300d318de99a2b4ad120d6a66d3ae241bff4e608b870491a85e54ff4 Homepage: http://zenoh.io Description: Zenoh plugin for ROS 2 and DDS in general . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/workflows/Release/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . . ------------------------------- # A Zenoh bridge for ROS 2 over DDS . [ROS](https://ros.org/) (the Robot Operating System) is a set of software libraries and tools allowing to build robotic applications. In its version 2, ROS 2 relies mostly on [O.M.G. DDS](https://www.dds-foundation.org/) as a [middleware for communications](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Different-Middleware-Vendors.html). This plugin bridges all ROS 2 communications using DDS over Zenoh. . While a Zenoh bridge for DDS already [exists](https://github.com/eclipse-zenoh/zenoh-plugin-dds) and helped lot of robotic use cases to overcome some [wireless connectivity](https://zenoh.io/blog/2021-03-23-discovery/), [bandwidth](https://zenoh.io/blog/2021-09-28-iac-experiences-from-the-trenches/) and [integration](https://zenoh.io/blog/2021-11-09-ros2-zenoh-pico/) issues, using a bridge dedicated to ROS 2 brings the following advantages: . - A better integration of the ROS graph (all ROS topics/services/actions can be seen across bridges) - A better support of ROS toolings (`ros2`, `rviz2`...) - Configuration of a ROS namespace on the bridge, instead of on each ROS Nodes - Easier integration with Zenoh native applications (services and actions are mapped to Zenoh Queryables) - More compact exchanges of discovery information between the bridges . ## Plugin or bridge ? . This software is built in 2 ways to choose from: - `zenoh-plugin-ros2dds`: a Zenoh plugin - a dynamic library that can be loaded by a Zenoh router - `zenoh-bridge-ros2dds`: a standalone executable . The features and configurations descibed in this document applies to both. Meaning the *"plugin"* and *"bridge"* words are interchangeables in the rest of this document. . ## How to install it . To install the latest release of either the DDS plugin for the Zenoh router, either the `zenoh-bridge-ros2dds` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-ros2dds/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-ros2dds--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-ros2dds--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-ros2dds` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-ros2dds`. - install the standalone executable with: `sudo apt install zenoh-bridge-ros2dds`. . ### Docker images . The **`zenoh-bridge-ros2dds`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-ros2dds/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-ros2dds:latest` for the latest release - `docker pull eclipse/zenoh-bridge-ros2dds:nightly` for the main branch version (nightly build) . ### Nightly builds . The ["Release" action](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/actions/workflows/release.yml) builds packages for most most of OSes. You can download those from the "Artifacts" section in each build. Just download the package for your OS and unzip it. You'll get 3 zips: 1 for the plugin, 1 for the plugin as debian package and 1 for the bridge. Unzip the `zenoh-bridge-ros2dds-.zip` file, and you can run `./zenoh-bridge-ros2dds` . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for DDS you need first to install the following dependencies: . - [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . - On Linux, make sure the `llvm` and `clang` development packages are installed: - on Debians do: `sudo apt install llvm-dev libclang-dev` - on CentOS or RHEL do: `sudo yum install llvm-devel clang-devel` - on Alpine do: `apk install llvm11-dev clang-dev` - [CMake](https://cmake.org/download/) (to build CycloneDDS which is a native dependency) . Once these dependencies are in place, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git $ cd zenoh-plugin-ros2dds $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-ros2dds` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. . . ## ROS 2 package You can also build `zenoh-bridge-ros2dds` as a ROS package running: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release ``` The `rosdep` command will automatically install *Rust* and *clang* as build dependencies. . If you want to cross-compile the package on x86 device for any target, you can use the following command: ```bash rosdep install --from-paths . --ignore-src -r -y colcon build --packages-select zenoh_bridge_ros2dds --cmake-args -DCMAKE_BUILD_TYPE=Release --cmake-args -DCROSS_ARCH= ``` where `` is the target architecture (e.g. `aarch64-unknown-linux-gnu`). The architechture list can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html). . The cross-compilation uses `zig` as a linker. You can install it with instructions in [here](https://ziglang.org/download/). Also, the `zigbuild` package is required to be installed on the target device. You can install it with instructions in [here](https://github.com/rust-cross/cargo-zigbuild#installation). . . ------------------------------- # Usage . A typical usage is to run 1 bridge in a robot, and 1 bridge in another host monitoring and operating the robot. . > :warning: The bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) and has been tested with `RMW_IMPLEMENTATION=rmw_cyclonedds_cpp`. While the DDS implementations are interoperable over UDP multicast and unicast, some specific and non-standard features of other DDS implementations (e.g. shared memory) might cause some issues. . It's important to make sure that NO DDS communication can occur between 2 hosts that are bridged by `zenoh-bridge-ros2dds`. Otherwise, some duplicate or looping traffic can occur. To make sure of this, you can either: - define `ROS_LOCALHOST_ONLY=1`. Preferably, enable MULTICAST on the loopback interface with this command (on Linux): `sudo ip l set lo multicast on` - use different `ROS_DOMAIN_ID` on each hosts - use a `CYCLONEDDS_URI` that configures CycloneDDS to only use internal interfaces to the robot. This configuration has to be used for all ROS Nodes as well as for the bridge. For instance for Turtlebot4 which embeds 2 hosts interconnected via USB: ```xml true ``` . On the robot, run: - `zenoh-bridge-ros2dds` . On the operating host run: - `zenoh-bridge-ros2dds -e tcp/:7447` - check if the robot's ROS interfaces are accessible via: - `ros2 topic list` - `ros2 service list` - `ros2 action list` . Other interconnectivity between the 2 bridges can be configured (e.g. automatic discovery via UDP multicast, interconnection via 1 or more Zenoh routers...). See the [Zenoh documentation](https://zenoh.io/docs/getting-started/deployment/) to learn more about the possibile deployments allowed by Zenoh. . . ## Configuration . `zenoh-bridge-ros2dds` can be configured via a JSON5 file passed via the `-c` argument. You can see a commented and exhaustive example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"ros2dds"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh-plugin_dds`) at startup and apply its configuration. . `zenoh-bridge-ros2dds` also allows some of those configuration values to be configured via command line arguments. Run this command to see which ones: - `zenoh-bridge-ros2dds -h` . The command line arguments overwrite the equivalent keys configured in a configuration file. . ## Connectivity configurations . ### DDS communications The bridge discovers all ROS 2 Nodes and their topics/services/actions running on the same Domain ID (set via `ROS_DOMAIN_ID` or `0` by default) via UDP multicast, as per DDS specification. . As the bridge relies on [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds), it's DDS communications can be configured via a CycloneDDS XML configuration file as explained [here](https://github.com/eclipse-cyclonedds/cyclonedds/tree/8638e1fa1e8ae9f964c91ad4763653702b8f91e0?tab=readme-ov-file#run-time-configuration). . ### Zenoh communications Starting from **v0.11.0**, the `zenoh-bridge-ros2dds` is by default started in `router` mode (See the difference between modes in Zenoh documentation: https://zenoh.io/docs/getting-started/deployment/). This means it's listening for incoming TCP connections by remote bridges or any Zenoh application on port `7447` via any network interface. It does perform discovery via scouting over UDP multicast or gossip protocol, but doesn't auto-connect to anything. As a consequence the connectivity between bridges has to be statically configured in one bridge connecting to the other (or several other bridges) via the `-e` command line option, or via the `connect` section in [configuration file](DEFAULT_CONFIG.json5). . If required, the automatic connection to other discovered bridges (also running in `router` mode) can be enabled adding such configuration: ```json5 scouting: { multicast: { autoconnect: { router: "router" } }, gossip: { autoconnect: { router: "router" } } }, ``` . Prior to **v0.11.0**, the `zenoh-bridge-ros2dds` was by default started in `peer` mode. It was listening for incoming TCP connections on a random port (chosen by the OS), and was automatically connecting to any discovered brige, router or peer. . ## Easy multi-robots via Namespace configuration . Deploying a `zenoh-bridge-ros2dds` in each robot and configuring each with its own namespace brings several benefits: . 1. No need to configure each ROS Node with a namespace. As the DDS traffic between all Nodes of a single robot remains internal to the robot, no namespace needs to be configured 2. Configuring each `zenoh-bridge-ros2dds` with `namespace: "/botX"` (where `'X'` is a unique id), each topic/service/action name routed to Zenoh is prefixed with `"/botX"`. Robots messages are not conflicting with each other. 3. On a monitoring/controlling host, you have 2 options: - Run a `zenoh-bridge-ros2dds` with `namespace: "/botX"` corresponding to 1 robot. Then to monitor/operate that specific robot, just any ROS Node without namespace. E.g.: `rviz2` - Run a `zenoh-bridge-ros2dds` without namespace. Then you can monitor/operate any robot remapping the namespace to the robot's one, or each topic/service/action name you want to use adding the robot's namespace as a prefix. E.g.: `rviz2 --ros-args -r /tf:=/botX2/tf -r /tf_static:=/botX/tf_static` . NOTE: the bridge prefixes ALL topics/services/actions names with the configured namespace, including `/rosout`, `/parameter_events`, `/tf` and `/tf_static`. . ## Admin space . The bridge exposes some internal states via a Zenoh admin space under `@ros2//**`, where `` is the unique id of the bridge (configurable). This admin space can be queried via Zenoh `get()` operation. If the REST plugin is configured for the bridge for instance via `--rest-http-port 8000` argument, those URLs can be queried: - [http://\:8000/@ros2/\/dds/**]() : to get all the DDS Readers/Writers discovered by the bridge - [http://\:8000/@ros2/\/node/**]() : to get all ROS nodes with their interfaces discovered by the bridge - [http://\:8000/@ros2/\/route/**]() : to get all routes between ROS interfaces and Zenoh established by the bridge Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds Package: zenoh-plugin-webserver Architecture: amd64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16119 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-webserver_0.11.0_amd64.deb Size: 2934776 MD5sum: db5ff97896c116745b240d0e3de1d79e SHA1: 38aabebaebe9fa4e388c65956995c2732f8fb996 SHA256: 29b3125d3d3c329913e500d9072cf6482d82e7f63ae61367573b58104810ed99 SHA512: fe9385584555049cfb9d0a013539d9e79c00f21fbe89dc02d5da1f440276fab2d236ee965ae4b7ef1f28a071c8317ce8ea5e9839b474239f4a97e25712f4c576 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: arm64 Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14735 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-webserver_0.11.0_arm64.deb Size: 2695884 MD5sum: 0cba0e4c60bba1faa7588280d0ce167e SHA1: 603fc29994fb4dcd560dfee5908616aaf4857184 SHA256: 0758f1921426a816345942a4982044c6c570dd723adc036148ccf566812a37fd SHA512: b9250be8accfccb1b31419985c1c80f522c08cd2421dfda8936239d10d573e1a16658aa53d641f129db7d122ff0f40b466f38b5c0daa9803eccb33563b223a8e Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: armel Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11584 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-webserver_0.11.0_armel.deb Size: 2403904 MD5sum: 93c484251d91906e142537e7373bb4e4 SHA1: d4da300231489ba3a813bea417d89cbf6aa8519c SHA256: 838fc1e36d986796578188984bd659c003f856f9ea4702457a449d2e9f81a774 SHA512: e1dbdc0460ed4134c6b7b88fea78b5d2981e84f2d61dfa1036c8e9c1585b44bcc5ef8d38d82943707f100ff7b723df0396798215245b189376101df9704fd897 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-plugin-webserver Architecture: armhf Version: 0.11.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11503 Depends: zenohd (=0.11.0) Filename: ./0.11.0/zenoh-plugin-webserver_0.11.0_armhf.deb Size: 2387056 MD5sum: 695cdd42b9ee93bebdc79acd5a5e69d4 SHA1: 1f361cdf184f4fc232fadfef60fd78672b6dff75 SHA256: 6c206329de806874c5017b1ab6186e50675efd8757dd8c45ab5a09eda654badd SHA512: 23ad171aadce9ebdef85b08d38582a4d1a467e14815e28515eaca85293f3b6f3fecd3745cfb409d25317182db31a79ddd811bd46df99da18e68a9667c6dabc86 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/actions?query=workflow%3A%22CI%22) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Web Server plugin . The Web Server plugin implements an HTTP server mapping URLs to zenoh keys. This plugin can be used to set-up a Web server where the resources are retrieved from geo-distributed zenoh storages, each leveraging various backends (file system, database, memory...). . **Library name** `zenoh_plugin_webserver` . :point_right: **Download stable versions:** https://download.eclipse.org/zenoh/zenoh-plugin-webserver/ . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ------------------------------- ## :warning: Documentation for previous 0.5 versions: The following documentation related to the version currently in development in "main" branch: 0.6.x. . For previous versions see the README and code of the corresponding tagged version: - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.9#readme) - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-plugin-webserver/tree/0.5.0-beta.8#readme) . ------------------------------- ## **Examples of usage** . Assuming you have a static website, you can: - expose the files as zenoh key/values using the [File System backend](https://github.com/eclipse-zenoh/zenoh-backend-filesystem) - set-up this Web Server plugin that will allow HTTP clients to browse the files. . Here are the steps: 1. Make sure the libraries for the File System backend and the Web Server plugin are available for the zenoh router: either installing their packages (depending your platform), either downloading the library files corresponding to your platform in your `~/.zenoh/lib` directory. 2. Copy the website files into a `~/.zenoh/zbackend_fs/my-site` directory (or make it a symbolic link to the path of your website) 3. Create a `zenoh.json5` configuration file containing: ```json5 { plugins: { webserver: { http_port: 8080, }, storage_manager: { volumes: { fs: {} }, storages: { demo: { key_expr: "my-site/**", strip_prefix: "my-site", volume: { id: "fs", dir: "my-site", read_only: true } } } } } } ``` 4. Start the zenoh router (`zenohd`). It will automatically load the Web Server plugin and make it available on port 8080. It will also create a storage replying to any zenoh query on key expressions starting with `my-site/`. Now you can browse your site on http://localhost:8080/my-site. . . For more advanced use cases you can also: - Have the files of your web sites stored on different hosts. Running a zenoh router with a File System Storage on each host allow to make all the files available under the `my-site/` zenoh key. - Duplicate the files of your web sites on several hosts to provide fault tolerance. - Start several zenoh routers with the Web Service plugin on different hosts (not necessarly the same than the hosts running the File System storages). Each host will serve your web site. - Use other backends than the File System to store your resources and make them available through zenoh. (List of available backends [here](http://zenoh.io/docs/manual/backends-list/)). - Deploy a zenoh application that will implement `eval` function for a resource, replying to requests with a dynamic content (see the `z_eval` example in [Rust](https://github.com/eclipse-zenoh/zenoh/blob/main/zenoh/examples/zenoh/z_eval.rs) or [Python](https://github.com/eclipse-zenoh/zenoh-python/blob/main/examples/zenoh/z_eval.py)). . ------------------------------- ## **Configuration** . In its configuration part, the plugin supports those settings: - **`http_port`** - int or string - required: either a port number as an integer or a string, either a string with format `":"` . ------------------------------- ## **Troubleshooting** . ### *Address already in use* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T14:20:51Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 48, kind: AddrInUse, message: "Address already in use" } ``` It means another process is already using this port number that the webserver plugin would like to use. In such case, you have 2 solutions: - stop the other process using this port - make the webserver plugin to another port changing its `listener` option. . ### *Permission denied* If in `zenohd` logs you see such error log at startup: ``` [2021-04-12T13:55:10Z ERROR zenoh_plugin_webserver] Unable to start http server for REST : Os { code: 13, kind: PermissionDenied, message: "Permission denied" ``` It probably means your OS (this usually happens on Linux) forbids the usage of the configured port for non-root user (actually it usually restricts all ports between 0 and 1024). In such case, you have 2 solutions: - run zenohd with root privileges (via `sudo`) - use another changing he webserver plugin's `listener` option. . ------------------------------- ## **How to build it** . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . To know the Rust version you're `zenohd` has been built with, use the `--version` option. Example: ```bash $ zenohd --version The zenoh router v0.6.0-beta.1 built with rustc 1.64.0 (a55dd71d5 2022-09-19) ``` Here, `zenohd` has been built with the rustc version `1.64.0`. Install and use this toolchain with the following command: . ```bash $ rustup default 1.64.0 ``` . And `zenohd` version corresponds to an un-released commit with id `1f20c86`. Update the `zenoh` dependency in Cargo.lock with this command: ```bash $ cargo update -p zenoh --precise 1f20c86 ``` . Then build the backend with: ```bash $ cargo build --release -p zenoh-plugin-webserver ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-webserver Package: zenoh-bridge-mqtt Architecture: amd64 Version: 0.11.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20184 Depends: libc6 (>= 2.29) Filename: ./0.11.1/zenoh-bridge-mqtt_0.11.1-1_amd64.deb Size: 4891624 MD5sum: 66743e6c525ec8301a5b14cb349311d8 SHA1: f97458a38025832db9d943b97146474a73554af3 SHA256: bde3f97eadb6d0068f9859cd795b37c4b4e689e233e0b1183728f3bd2193b50b SHA512: 7b56f574c7f1bf643cc1eb4198227c2224c7184f626a735208488c89b9d463b3ea290dded18729239bfe08cca3a0b910324e02c9fc9bdc792130df6880ba7717 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: arm64 Version: 0.11.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17965 Filename: ./0.11.1/zenoh-bridge-mqtt_0.11.1-1_arm64.deb Size: 4378804 MD5sum: edb48b86a3f6acbf47cb8c010ca04ed3 SHA1: ecba0ec6fb01588de183f4054c38f33f36281a6b SHA256: b3f758a67ed39ed589d723ede4fbafb6425974be11e21236f1f9fbe91f144c3b SHA512: e3635a72ec273b7bd8cbe2762fd6c5ae88eab0f67d68124c00f3f8961bfd379b40097be3e631487a255df49d6c2046af27ce3ad64295cc6b83fe88d530a337f2 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: armel Version: 0.11.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19517 Filename: ./0.11.1/zenoh-bridge-mqtt_0.11.1-1_armel.deb Size: 4710360 MD5sum: 874add98daa1695d45d473ec50dfd16f SHA1: 5fa601a4f3f3ab73dd41930acabf773859cfbb76 SHA256: f11d362c6d04caaf6e2ecee1380d66c03c8dab5a3ea8baae1e4b0f6ff2d1fa8d SHA512: 3aa6165e9d3029ffb886696587252696a66b93ab02d30a9c91d7708c496b90348758761b7748260564993d9ecb4f9dbf8754bc3c6cfdf05cc2dbbdc732cd5768 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-bridge-mqtt Architecture: armhf Version: 0.11.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19258 Filename: ./0.11.1/zenoh-bridge-mqtt_0.11.1-1_armhf.deb Size: 4732620 MD5sum: c6c5a6e766d27a93fff1d3b357635a75 SHA1: 4b2e90fa83844367a517f9a10dd61b9ea0e797c2 SHA256: 09f69324646a232c82585ee5ad9e8808fa85286130b4ffc6acb54b4bd2994be5 SHA512: adf98dfc07763c04a8f12d1d06c5e3ba7ff7645a3720c14718b8164405d214ede8a2d5055f199681b6fea9e2d06d03da3ccc233a70cb66bd779cee90f64e0fac Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: amd64 Version: 0.11.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14856 Depends: zenohd (=0.11.0-1) Filename: ./0.11.1/zenoh-plugin-mqtt_0.11.1-1_amd64.deb Size: 3017512 MD5sum: 0c4655cb4976651bf0817c916005c79e SHA1: 975497c395ba1fe593eea2fd9d96477177d813ac SHA256: a04a9298bd07241d1e3e685cfc02f5e5cadd99bbe03d5f8ba930e983279ba867 SHA512: bc0c5dff8011a53233094e6b8fbf7b0c73dcdc8475202cd92b9b7dcf833a4d93130289e9425432a1e6de3695b5328fc820f73679499d8bdb719e253391ccaf6a Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--tx-channel-size `** : Size of the MQTT transmit channel (default: 65536). The channel buffers messages from Zenoh until they can be sent to MQTT clients. If the channel capacity is reached new messages from Zenoh will be dropped until space becomes available. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: arm64 Version: 0.11.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13077 Depends: zenohd (=0.11.0-1) Filename: ./0.11.1/zenoh-plugin-mqtt_0.11.1-1_arm64.deb Size: 2662572 MD5sum: 6363fbbbc31c8e8bc530f0a694d40aa1 SHA1: a98555e250eb586fe6b246e28fcb0a60bbe016ee SHA256: a6ab888b973579eaeae77e246b20bd05b2fecf545c39f0c9151b6ddec8ac74d0 SHA512: 54dec37fa587ac9a4a8f5e450d93f54c48486240e9cead70a96b22aca1109b3a6ed0acc34c7959fac1c509dba3d28f2c1b1572171df4b25b05a8d9ecc1d81e8f Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--tx-channel-size `** : Size of the MQTT transmit channel (default: 65536). The channel buffers messages from Zenoh until they can be sent to MQTT clients. If the channel capacity is reached new messages from Zenoh will be dropped until space becomes available. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: armel Version: 0.11.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12339 Depends: zenohd (=0.11.0-1) Filename: ./0.11.1/zenoh-plugin-mqtt_0.11.1-1_armel.deb Size: 2665304 MD5sum: 9f350aef5552964365924d2da2bd30af SHA1: af1c01177fce5986874fa7c64a80d9ee276dda6a SHA256: 3c8b087f0a629844853c94409e88932a5477855c488a0c1ed70b5d4881118a8c SHA512: 1a184300969f1cf42c9212330a21baa8554b93cc8e891bef0d2cc37dca912feb8b3a79c17b3eaba962ebeec2bf30707e8cfb3e92294670e93167f7b293c347dc Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--tx-channel-size `** : Size of the MQTT transmit channel (default: 65536). The channel buffers messages from Zenoh until they can be sent to MQTT clients. If the channel capacity is reached new messages from Zenoh will be dropped until space becomes available. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: zenoh-plugin-mqtt Architecture: armhf Version: 0.11.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12305 Depends: zenohd (=0.11.0-1) Filename: ./0.11.1/zenoh-plugin-mqtt_0.11.1-1_armhf.deb Size: 2708976 MD5sum: 3de1ee66fdfc2248e09e7f98a9f787bd SHA1: 2f1453000468e29efba22be83c0652ca7b3a671d SHA256: c8cbf555f47d8c2a54f0596894b63e1fa47405c7b64be46e70366bda76a251d7 SHA512: 48d578da457ce53c8c7a11ce66ea6a9303b10e1f170d840bd2133b6c8061f5a63378e559fbc4374def768120a1615e1720840b070282e8f2f3052860a5b46bf0 Homepage: http://zenoh.io Description: Zenoh plugin for MQTT . [![CI](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/workflows/Rust/badge.svg)](https://github.com/eclipse-zenoh/zenoh-plugin-mqtt/actions?query=workflow%3ARust) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # MQTT plugin and standalone `zenoh-bridge-mqtt` . :point_right: **Install latest release:** see [below](#How-to-install-it) . :point_right: **Docker image:** see [below](#Docker-image) . :point_right: **Build "main" branch:** see [below](#How-to-build-it) . ## Background . [MQTT](https://mqtt.org/) is a pub/sub protocol leveraging a broker to route the messages between the MQTT clients. The MQTT plugin for Eclipse Zenoh acts as a MQTT broker, accepting connections from MQTT clients (V3 and V5) and translating the MQTT pub/sub into a Zenoh pub/sub. I.e.: - a MQTT publication on topic `device/123/temperature` is routed as a Zenoh publication on key expression `device/123/temperature` - a MQTT subscription on topic `device/#` is mapped to a Zenoh subscription on key expression `device/**` . This allows a close intergration of any MQTT system with Zenoh, but also brings to MQTT systems the benefits of a Zenoh routing infrastructure. Some examples of use cases: - Routing MQTT from the device to the Edge and to the Cloud - Bridging 2 distinct MQTT systems across the Internet, with NAT traversal - Pub/sub to MQTT via the Zenoh REST API - MQTT-ROS2 (robot) communication - Store MQTT publications in any Zenoh storage (RocksDB, InfluxDB, file system...) - MQTT record/replay with InfluxDB as a storage . The MQTT plugin for Eclipse Zenoh is available either as a dynamic library to be loaded by the Zenoh router (`zenohd`), either as a standalone executable (`zenoh-bridge-mqtt`) that can acts as a Zenoh client or peer. . ## Configuration . `zenoh-bridge-mqtt` can be configured via a JSON5 file passed via the `-c`argument. You can see a commented example of such configuration file: [`DEFAULT_CONFIG.json5`](DEFAULT_CONFIG.json5). . The `"mqtt"` part of this same configuration file can also be used in the configuration file for the zenoh router (within its `"plugins"` part). The router will automatically try to load the plugin library (`zenoh_plugin_mqtt`) at startup and apply its configuration. . `zenoh-bridge-mqtt` also accepts the following arguments. If set, each argument will override the similar setting from the configuration file: * zenoh-related arguments: - **`-c, --config `** : a config file - **`-m, --mode `** : The zenoh session mode. Default: `peer` Possible values: `peer` or `client`. See [zenoh documentation](https://zenoh.io/docs/getting-started/key-concepts/#deployment-units) for more details. - **`-l, --listen `** : A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. Example of locator: `tcp/localhost:7447`. - **`-e, --peer `** : A peer locator this router will try to connect to (typically another bridge or a zenoh router). Repeat this option to connect to several peers. Example of locator: `tcp/:7447`. - **`--no-multicast-scouting`** : disable the zenoh scouting protocol that allows automatic discovery of zenoh peers and routers. - **`-i, --id `** : The identifier (as an hexadecimal string - e.g.: 0A0B23...) that the zenoh bridge must use. **WARNING: this identifier must be unique in the system!** If not set, a random UUIDv4 will be used. - **`--rest-http-port [PORT | IP:PORT]`** : Configures HTTP interface for the REST API (disabled by default, setting this option enables it). Accepted values: - a port number - a string with format `:` (to bind the HTTP server to a specific interface). * MQTT-related arguments: - **`-p, --port [PORT | IP:PORT]`** : The address to bind the MQTT server. Default: `"0.0.0.0:1883"`. Accepted values: - a port number (`"0.0.0.0"` will be used as IP to bind, meaning any interface of the host) - a string with format `:` (to bind the MQTT server to a specific interface). - **`-s, --scope `** : A string added as prefix to all routed MQTT topics when mapped to a zenoh key expression. This should be used to avoid conflicts when several distinct MQTT systems using the same topics names are routed via Zenoh. - **`-a, --allow `** : A regular expression matching the MQTT topic name that must be routed via zenoh. By default all topics are allowed. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`--deny `** : A regular expression matching the MQTT topic name that must not be routed via zenoh. By default no topics are denied. If both `--allow` and `--deny` are set a topic will be allowed if it matches only the 'allow' expression. - **`-w, --generalise-pub `** : A list of key expressions to use for generalising the declaration of the zenoh publications, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`-r, --generalise-sub `** : A list of key expressions to use for generalising the declaration of the zenoh subscriptions, and thus minimizing the discovery traffic (usable multiple times). See [this blog](https://zenoh.io/blog/2021-03-23-discovery/#leveraging-resource-generalisation) for more details. - **`--tx-channel-size `** : Size of the MQTT transmit channel (default: 65536). The channel buffers messages from Zenoh until they can be sent to MQTT clients. If the channel capacity is reached new messages from Zenoh will be dropped until space becomes available. - **`--dictionary-file `** : Path to a file containing the MQTT client username/password dictionary. - **`--server-private-key `** : Path to the TLS private key for the MQTT server. If specified a valid certificate for the server must also be provided. - **`--server-certificate `** : Path to the TLS public certificate for the MQTT server. If specified a valid private key for the server must also be provided. - **`--root-ca-certificate `** : Path to the certificate of the certificate authority used to validate clients connecting to the MQTT server. If specified a valid private key and certificate for the server must also be provided. . ## Admin space . The zenoh bridge for MQTT exposes an administration space allowing to get some information on its status and configuration. This administration space is accessible via any zenoh API, including the REST API that you can activate at `zenoh-bridge-mqtt` startup using the `--rest-http-port` argument. . The `zenoh-bridge-mqtt` exposes this administration space with paths prefixed by `@/service//mqtt` (where `` is the unique identifier of the bridge instance). The informations are then organized with such paths: - `@/service//mqtt/version` : the bridge version - `@/service//mqtt/config` : the bridge configuration . Example of queries on administration space using the REST API with the `curl` command line tool (don't forget to activate the REST API with `--rest-http-port 8000` argument): - ```bash curl http://localhost:8000:/@/service/** ``` . > _Pro tip: pipe the result into [**jq**](https://stedolan.github.io/jq/) command for JSON pretty print or transformation._ . ## MQTTS support . The MQTT plugin and standalone bridge for Eclipse Zenoh supports MQTTS. MQTTS can be configured in two ways: . - server side authentication: MQTT clients validate the servers TLS certificate but not the other way around. - mutual authentication (mTLS): where both server and clients validate each other. . MQTTS can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . ### Server side authentication configuration . Server side authentication requires both a private key and certificate for the server. These can be provided as either a file or as a base 64 encoded string. . In the configuration file, the required **tls** fields when using files are **server_private_key** and **server_certificate**. When using base 64 encoded strings the required **tls** fields are **server_private_key_base64** and **server_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem" } } } } ``` . The standalone bridge (`zenoh-bridge-mqtt`) also allows the required files to be provided through the **`--server-private-key`** and **`--server-certificate`** command line arguments. . ### Mutual authentication (mTLS) configuration . In order to enable mutual authentication a certificate for the certificate authority used to validate clients connecting to the MQTT server must also be provided. This can be provided as either a file or a base 64 encoded string. . In the configuration file, the required **tls** field when using a file is **root_ca_certificate**. When using base 64 encoded strings the required **tls** field when using a file is **root_ca_certificate_base64**. . An example configuration file supporting server side authentication would be: . ```json { "plugins": { "mqtt": { "tls": { "server_private_key": "/path/to/private-key.pem", "server_certificate": "/path/to/certificate.pem", "root_ca_certificate": "/path/to/root-ca-certificate.pem" } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--root-ca-certificate`** command line argument. . ## Username/password authentication . The MQTT plugin and standalone bridge for Eclipse Zenoh supports basic username/password authentication of MQTT clients. Credentials are provided via a dictionary file with each line containing the username and password for a single user in the following format: . ``` username:password ``` . Username/passord authentication can be configured via the configuration file or, if using the standalone bridge, via command line arguments. . In the configuration file, the required **auth** field for configuring the dictionary file is **dictionary_file**. . An example configuration file supporting username/password authentication would be: . ```json { "plugins": { "mqtt": { "auth": { "dictionary_file": "/path/to/dictionary-file", } } } } ``` The standalone bridge (`zenoh-bridge-mqtt`) also allows the required file to be provided through the **`--dictionary-file`** command line argument. . ### Security considerations . Usernames and passwords are sent as part of the MQTT `CONNECT` message in clear text. As such, they can potentially be viewed using tools such as [Wireshark](https://www.wireshark.org/). . To prevent this, it is highly recommended that this feature is used in conjunction with the MQTTS feature to ensure credentials are encrypted on the wire. . ## How to install it . To install the latest release of either the MQTT plugin for the Zenoh router, either the `zenoh-bridge-mqtt` standalone executable, you can do as follows: . ### Manual installation (all platforms) . All release packages can be downloaded from: - https://download.eclipse.org/zenoh/zenoh-plugin-mqtt/latest/ . Each subdirectory has the name of the Rust target. See the platforms each target corresponds to on https://doc.rust-lang.org/stable/rustc/platform-support.html . Choose your platform and download: - the `zenoh-plugin-mqtt--.zip` file for the plugin. Then unzip it in the same directory than `zenohd` or to any directory where it can find the plugin library (e.g. /usr/lib) - the `zenoh-bridge-mqtt--.zip` file for the standalone executable. Then unzip it where you want, and run the extracted `zenoh-bridge-mqtt` binary. . ### Linux Debian . Add Eclipse Zenoh private repository to the sources list: . ```bash echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null sudo apt update ``` Then either: - install the plugin with: `sudo apt install zenoh-plugin-mqtt`. - install the standalone executable with: `sudo apt install zenoh-bridge-mqtt`. . . ## Docker image The **`zenoh-bridge-mqtt`** standalone executable is also available as a [Docker images](https://hub.docker.com/r/eclipse/zenoh-bridge-mqtt/tags?page=1&ordering=last_updated) for both amd64 and arm64. To get it, do: - `docker pull eclipse/zenoh-bridge-mqtt:latest` for the latest release - `docker pull eclipse/zenoh-bridge-mqtt:main` for the main branch version (nightly build) . Usage: **`docker run --init -p 1883:1883 eclipse/zenoh-bridge-mqtt`** It supports the same command line arguments than the `zenoh-bridge-mqtt` (see above or check with `-h` argument). . . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. . > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version than `zenohd`, and using for `zenoh` dependency the same version (or commit number) than 'zenohd'. Otherwise, incompatibilities in memory mapping of shared types between `zenohd` and the library can lead to a `"SIGSEV"` crash. . In order to build the zenoh bridge for MQTT you only need to install [Rust](https://www.rust-lang.org/tools/install). If you already have the Rust toolchain installed, make sure it is up-to-date with: . ```bash $ rustup update ``` . Then, you may clone the repository on your machine: . ```bash $ git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git $ cd zenoh-plugin-mqtt $ cargo build --release ``` . The standalone executable binary `zenoh-bridge-mqtt` and a plugin shared library (`*.so` on Linux, `*.dylib` on Mac OS, `*.dll` on Windows) to be dynamically loaded by the zenoh router `zenohd` will be generated in the `target/release` subdirectory. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Vcs-Git: https://github.com/eclipse-zenoh/zenoh-plugin-mqtt Package: libzenohc-dev Architecture: amd64 Version: 0.5.0~beta.8 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 48 Depends: libzenohc (=0.5.0~beta.8) Filename: ./0.5.0-beta.8/libzenohc-dev_0.5.0~beta.8_amd64.deb Size: 12888 MD5sum: 585fd036ec2de626f3b9b14355e14fff SHA1: 8d5a33e180ff614c7a68fc207e1612236d2df3b6 SHA256: 243e24737fe995896bb003616f0d96cdae475f738f193972d33592f8a7f033da SHA512: 88253313018d14f9654cb754f47b4cf247b9699bbc207b456aca9236ad693123f7e1eaf6ca5605adf3f3ba0be7876acc9a83342b4c91929c14953beee466f8a7 Homepage: http://zenoh.io Description: The zenoh C client API Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Standards-Version: 3.9.4 Package: libzenohc Architecture: amd64 Version: 0.5.0~beta.8 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7690 Depends: Filename: ./0.5.0-beta.8/libzenohc_0.5.0~beta.8_amd64.deb Size: 2073142 MD5sum: f0d86fe78c9582d3f61db0542ba7cab2 SHA1: a7aa7d226a99b0dc0bcec58faada5e1203a64481 SHA256: c92b0a8ea60c9ca96b1c0888e98737171ac7296732adda206dcfc0dd610bcf29 SHA512: 8d07fc75b595bee3a1c08219966160c9582a29feb31d37ef89336547c281e18c1c1a962b2d5baeb9ef108f93cb2a0bda8d49b1c5f1fb1fde0c625c3b1eab5396 Homepage: http://zenoh.io Description: The zenoh C client API Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Standards-Version: 3.9.4 Package: zenoh-rest Architecture: amd64 Version: 0.5.0~beta.8 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5149 Depends: zenohd (=0.5.0~beta.8) Filename: ./0.5.0-beta.8/zenoh-rest_0.5.0~beta.8_amd64.deb Size: 1629486 MD5sum: 7a669486892a2acdefd878b3ca8d971f SHA1: 0e16f8538c7abda5e0680db29b1f9bb545784467 SHA256: c367b995ec5b00cf745626bbea6ffb7edcd24a161a6f39625b3a994eb780d1b5 SHA512: 689958780d61d044c983cbe215f45619e5b240f38c3f59d23b316954a4af50b4846dd023732567adb016984a240fc8538a88143272f0fa0d35fa8e79b39a0a31 Homepage: http://zenoh.io Description: The zenoh REST plugin Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Standards-Version: 3.9.4 Package: zenoh-rest Architecture: armhf Version: 0.5.0~beta.8 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4310 Depends: zenohd (=0.5.0~beta.8) Filename: ./0.5.0-beta.8/zenoh-rest_0.5.0~beta.8_armhf.deb Size: 1377140 MD5sum: 32180fd0b4426781af042c7b636c709b SHA1: 8dfc162da061400b657036ab22d207f868271193 SHA256: ae669d183c0f86b1d8fd2d22f6c896d5a83f71173e373254513ec8c512ac8c4e SHA512: 83c7b14c4bdac8045870b680a984f493aa8fefe9929ee21647ec9ef70fc4b2c8a25d78c24018bec8cf77cc36984730f131edd8054cc602d03f4ff50c09b70880 Homepage: http://zenoh.io Description: The zenoh REST plugin Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh-storages Architecture: amd64 Version: 0.5.0~beta.8 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4426 Depends: zenohd (=0.5.0~beta.8) Filename: ./0.5.0-beta.8/zenoh-storages_0.5.0~beta.8_amd64.deb Size: 1444490 MD5sum: 859354dd5de3eb096002555e3dfa5bea SHA1: 91f921dad83b9b98b880b2bf315d152b01f759a4 SHA256: ceea0acf4ea78c05ecd4e823d2614d4462bd296f96d9f5fd20bc73eb1a58f5eb SHA512: 5a447419894491d23aaf26127aa835ac0c2e152ac239680d7ecf8b88c64ce492f33fa7dc82472dc3a6f8e1ca32a1dee4a6be8e27873abb6a52e5a899cb27cf23 Homepage: http://zenoh.io Description: The zenoh storages plugin. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Standards-Version: 3.9.4 Package: zenoh-storages Architecture: armhf Version: 0.5.0~beta.8 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3804 Depends: zenohd (=0.5.0~beta.8) Filename: ./0.5.0-beta.8/zenoh-storages_0.5.0~beta.8_armhf.deb Size: 1218344 MD5sum: d57ec5961e0ba07021b841d9e0d00220 SHA1: 758cf13a6fb43aa479c40ad64a5dfb22b4ff64b7 SHA256: a2b6ac5486fef3a985d9c58c82613af33f65a036d215236c8edcdab3955b6ecc SHA512: 5dd1ec75e51ef1afe211ddae5342c330d773fe96b741ca57ea86da63bb21983bc9c2077747156ce79ff165b865c6708584289a758aff768a4f6a287a75045cbd Homepage: http://zenoh.io Description: The zenoh storages plugin. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: amd64 Version: 0.5.0~beta.8 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.5.0~beta.8), zenoh-rest (=0.5.0~beta.8), zenoh-storages (=0.5.0~beta.8) Filename: ./0.5.0-beta.8/zenoh_0.5.0~beta.8_amd64.deb Size: 824 MD5sum: 22e955cd92d0a9603bd0a1a2d809b58e SHA1: d7e0f20f834dc838d0adffed2ffb15e43f64378e SHA256: a5d4da943adf04a611439d956558c61eacb8638abb177bec372595d409929114 SHA512: 7d3ba006c0a6eddf45687fd7ca54c072e1ef5757d2680f246f89512f97af845f4375717d0e5f8510041eacffb1e006acf202b33be50e80551668d495eae39163 Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenoh Architecture: armhf Version: 0.5.0~beta.8 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.5.0~beta.8), zenoh-rest (=0.5.0~beta.8), zenoh-storages (=0.5.0~beta.8) Filename: ./0.5.0-beta.8/zenoh_0.5.0~beta.8_armhf.deb Size: 824 MD5sum: a3b6955845893e5d2d9bd67cca6960a9 SHA1: 2cd60fc54ba48689565f61bb75b43672c514f8a7 SHA256: 3e8bad019be354cdbe32b2e4aeae1aae66f3430863b5edfd606e3ece389197cc SHA512: 94d8e91ea9fd2bfb1537283f184147ec70da63eaf315c9cad12746ff339ff55d7e17db9e32e1e90342144df91c2f31f54f35fa6b5349bdd10f40d77d61850af7 Homepage: http://zenoh.io Description: The zenoh top-level package Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: zenohd Architecture: amd64 Version: 0.5.0~beta.8 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4706 Depends: Filename: ./0.5.0-beta.8/zenohd_0.5.0~beta.8_amd64.deb Size: 1545550 MD5sum: 9d2afd9f47aa9678db8793cf77d2f088 SHA1: 9eb033c4a12f9a589d1a85defff90c2e18d2585c SHA256: 3a192938053754aba7330d946a9842fcbd6602482fda77f9bf9d85c3a279e074 SHA512: 7f940d0bb1c558912c18171b58712663495a34015ebb4dc5e2b27a733c2bac03f150f6b8071941619bd0bd185907ebb68874a0e52de41cf91b43152766b99052 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. ![zenoh banner](http://zenoh.io/img/zenoh-dragon-small.png) . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Gitter](https://badges.gitter.im/atolab/zenoh.svg)](https://gitter.im/atolab/zenoh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse zenoh The Eclipse zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Eclipse zenoh /zeno/ unifies data in motion, data in-use, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) for more detailed information. . ------------------------------- ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Currently, zenoh requires a nightly version of Rust, type the following to install it after you have followed the previous instructions: . ```bash $ rustup default nightly ``` . And then build zenoh with: . ```bash $ cargo build --release --all-targets ``` . ------------------------------- ## How to test it . For convenience, the zenoh router is pre-build and made available in a Docker image: https://hub.docker.com/r/eclipse/zenoh . Thus, run it just doing: ```bash docker pull eclipse/zenoh:latest docker run --init -p 7447:7447/tcp -p 7447:7447/udp -p 8000:8000/tcp eclipse/zenoh:latest ``` . The ports used by zenoh are the following: . - **7447/tcp** : the zenoh protocol via TCP - **7447/udp** : the zenoh scouting protocol using UDP multicast (for clients to automatically discover the router) - **8000/tcp** : the zenoh REST API . . All the examples are compiled into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router (`target/release/zenohd`). . Then, you can test it using the zenoh API in your favorite language: . - **Rust** using the [zenoh crate](https://crates.io/crates/zenoh) and the [examples in this repo](https://github.com/eclipse-zenoh/zenoh/tree/master/zenoh/examples) - **Python** using [zenoh-python](https://github.com/eclipse-zenoh/zenoh-python) . Or with the **REST** API: . ## Examples of usage with the REST API . The complete Eclipse zenoh's key/value space is accessible through the REST API, using regular HTTP GET, PUT and DELETE methods. In those examples, we use the **curl** command line tool. . ### Managing the admin space . * Get info of the local zenoh router: ``` curl http://localhost:8000/@/router/local ``` * Get the backends of the local router (only memory by default): ``` curl 'http://localhost:8000/@/router/local/**/backend/*' ``` * Get the storages of the local router (none by default): ``` curl 'http://localhost:8000/@/router/local/**/storage/*' ``` * Add a memory storage on `/demo/example/**`: ``` curl -X PUT -H 'content-type:application/properties' -d 'path_expr=/demo/example/**' http://localhost:8000/@/router/local/plugin/storages/backend/memory/storage/my-storage . ``` . ### Put/Get into zenoh Assuming the memory storage has been added, as described above, you can now: . * Put a key/value into zenoh: ``` curl -X PUT -d 'Hello World!' http://localhost:8000/demo/example/test ``` * Retrieve the key/value: ``` curl http://localhost:8000/demo/example/test ``` * Remove the key value ``` curl -X DELETE http://localhost:8000/demo/example/test ``` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Standards-Version: 3.9.4 Package: zenohd Architecture: armhf Version: 0.5.0~beta.8 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4005 Filename: ./0.5.0-beta.8/zenohd_0.5.0~beta.8_armhf.deb Size: 1306092 MD5sum: 25b6bba0139d7bbcd7f58dcd716e0da2 SHA1: 9115b35e7c2ff89c389c37137326745a4189dbad SHA256: a019abe57a78e6a9db010d4974e62c1f1d6386edc96230a4ec2ac07cedd7a847 SHA512: 4b6d6e00eb684c86acebf6aafd0c2728bb4c9660f102cd86acf26beb253da084547be6994a8a44b7c2b2e9541061755a7cc33fe2543754d57918df994b2c5357 Homepage: http://zenoh.io Description: Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. ![zenoh banner](http://zenoh.io/img/zenoh-dragon-small.png) . [![CI](https://github.com/eclipse-zenoh/zenoh/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![Gitter](https://badges.gitter.im/atolab/zenoh.svg)](https://gitter.im/atolab/zenoh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse zenoh The Eclipse zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Eclipse zenoh /zeno/ unifies data in motion, data in-use, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) for more detailed information. . ------------------------------- ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Currently, zenoh requires a nightly version of Rust, type the following to install it after you have followed the previous instructions: . ```bash $ rustup default nightly ``` . And then build zenoh with: . ```bash $ cargo build --release --all-targets ``` . ------------------------------- ## How to test it . For convenience, the zenoh router is pre-build and made available in a Docker image: https://hub.docker.com/r/eclipse/zenoh . Thus, run it just doing: ```bash docker pull eclipse/zenoh:latest docker run --init -p 7447:7447/tcp -p 7447:7447/udp -p 8000:8000/tcp eclipse/zenoh:latest ``` . The ports used by zenoh are the following: . - **7447/tcp** : the zenoh protocol via TCP - **7447/udp** : the zenoh scouting protocol using UDP multicast (for clients to automatically discover the router) - **8000/tcp** : the zenoh REST API . . All the examples are compiled into the `target/release/examples` directory. They can all work in peer-to-peer, or interconnected via the zenoh router (`target/release/zenohd`). . Then, you can test it using the zenoh API in your favorite language: . - **Rust** using the [zenoh crate](https://crates.io/crates/zenoh) and the [examples in this repo](https://github.com/eclipse-zenoh/zenoh/tree/master/zenoh/examples) - **Python** using [zenoh-python](https://github.com/eclipse-zenoh/zenoh-python) . Or with the **REST** API: . ## Examples of usage with the REST API . The complete Eclipse zenoh's key/value space is accessible through the REST API, using regular HTTP GET, PUT and DELETE methods. In those examples, we use the **curl** command line tool. . ### Managing the admin space . * Get info of the local zenoh router: ``` curl http://localhost:8000/@/router/local ``` * Get the backends of the local router (only memory by default): ``` curl 'http://localhost:8000/@/router/local/**/backend/*' ``` * Get the storages of the local router (none by default): ``` curl 'http://localhost:8000/@/router/local/**/storage/*' ``` * Add a memory storage on `/demo/example/**`: ``` curl -X PUT -H 'content-type:application/properties' -d 'path_expr=/demo/example/**' http://localhost:8000/@/router/local/plugin/storages/backend/memory/storage/my-storage . ``` . ### Put/Get into zenoh Assuming the memory storage has been added, as described above, you can now: . * Put a key/value into zenoh: ``` curl -X PUT -d 'Hello World!' http://localhost:8000/demo/example/test ``` * Retrieve the key/value: ``` curl http://localhost:8000/demo/example/test ``` * Remove the key value ``` curl -X DELETE http://localhost:8000/demo/example/test ``` . Vcs-Browser: https://github.com/eclipse-zenoh/zenoh Vcs-Git: https://github.com/eclipse-zenoh/zenoh Package: libzenohc-dev Architecture: amd64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 53 Depends: libzenohc (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/libzenohc-dev_0.5.0~beta.9_amd64.deb Size: 14092 MD5sum: eed8e09ae8747338a31beca66ab62470 SHA1: 3b9b3a0239be13c05e4c36dd004e89253c8d5998 SHA256: 1b4bc0e12d6b454e80a29ad17de26354fac97433a4c62219c0a74c65e08e2882 SHA512: ddd982ca986019e1afea539e8e417cec4409aef124ebce318c501b9e660c2d82a9af98e007e9cdd5ae3d0976a823ef6f447bf1343fa24cf9172f1222a70c47c8 Homepage: http://zenoh.io Description: The zenoh C client API ![zenoh banner](./zenoh-dragon.png) . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Gitter](https://badges.gitter.im/atolab/zenoh.svg)](https://gitter.im/atolab/zenoh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse zenoh C Client API . [Eclipse zenoh](http://zenoh.io) is an extremely efficient and fault-tolerant [Named Data Networking](http://named-data.net) (NDN) protocol that is able to scale down to extremely constrainded devices and networks. . ------------------------------- ## How to install it . Work in progress... . ------------------------------- ## How to build it . 1. Make sure that [rust](https://www.rust-lang.org) is available on your platform: . -- Ubuntu -- . ```bash $ sudo apt-get install rustc ``` . -- MacOS -- . ```bash $ brew install rust ``` . 2. Clone the [source] with `git`: . ```sh git clone https://github.com/eclipse-zenoh/zenoh-c.git cd rust ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ make $ make install # on linux use **sudo** ``` . If you want to build with debug symbols set the `BUILD_TYPE=Debug` environment variable before running `make` and `make install`: . ```bash $ cd /path/to/zenoh-c $ export BUILD_TYPE=Debug $ make $ make install # on linux use **sudo** ``` . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ make examples ``` . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/zn_sub ``` . ```bash $ ./target/release/examples/zn_pub ``` . ### Eval and Query Example ```bash $ ./target/release/examples/zn_eval ``` . ```bash $ ./target/release/examples/zn_query ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/zn_sub_thgr ``` . ```bash $ ./target/release/examples/zn_pub_thgr ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 53 Depends: libzenohc (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/libzenohc-dev_0.5.0~beta.9_arm64.deb Size: 14080 MD5sum: d9aa2e60bccc3a851e758b906c31a7fb SHA1: 72c1b56dfeabcda8ea2d76f7db720897f8784770 SHA256: d9f4d8f9d0a6a42e7e8dec7fa3c3ae359141badf53226751cb435d08f4425f2f SHA512: ab45872c38c40242f8a3a4b0aeab84169a72cf8ec56d080c191cf7c9ae7ced87fec6e30e26ce05cff2655d7c10e2113b9bfa4865cddd0c529cc32a603f05488f Homepage: http://zenoh.io Description: The zenoh C client API ![zenoh banner](./zenoh-dragon.png) . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Gitter](https://badges.gitter.im/atolab/zenoh.svg)](https://gitter.im/atolab/zenoh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse zenoh C Client API . [Eclipse zenoh](http://zenoh.io) is an extremely efficient and fault-tolerant [Named Data Networking](http://named-data.net) (NDN) protocol that is able to scale down to extremely constrainded devices and networks. . ------------------------------- ## How to install it . Work in progress... . ------------------------------- ## How to build it . 1. Make sure that [rust](https://www.rust-lang.org) is available on your platform: . -- Ubuntu -- . ```bash $ sudo apt-get install rustc ``` . -- MacOS -- . ```bash $ brew install rust ``` . 2. Clone the [source] with `git`: . ```sh git clone https://github.com/eclipse-zenoh/zenoh-c.git cd rust ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ make $ make install # on linux use **sudo** ``` . If you want to build with debug symbols set the `BUILD_TYPE=Debug` environment variable before running `make` and `make install`: . ```bash $ cd /path/to/zenoh-c $ export BUILD_TYPE=Debug $ make $ make install # on linux use **sudo** ``` . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ make examples ``` . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/zn_sub ``` . ```bash $ ./target/release/examples/zn_pub ``` . ### Eval and Query Example ```bash $ ./target/release/examples/zn_eval ``` . ```bash $ ./target/release/examples/zn_query ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/zn_sub_thgr ``` . ```bash $ ./target/release/examples/zn_pub_thgr ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 53 Depends: libzenohc (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/libzenohc-dev_0.5.0~beta.9_armel.deb Size: 14096 MD5sum: eb02c5993f610fb0100b3af8e38f9a82 SHA1: 7b87dd06ed1f46d29d41a6a1aa8838cbd3a6c52a SHA256: 8e83c883e47ffce5876648cc699db899800cd7e03d1a5964437dedd217e72b08 SHA512: bb6013d3fb35b08194bccbf2616b592ab371c9c650ef446c2d423d393a5b95b3d82b778ffceaa5d282cf73c829a989865aa3197e8c994f7818de77592213c9cf Homepage: http://zenoh.io Description: The zenoh C client API ![zenoh banner](./zenoh-dragon.png) . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Gitter](https://badges.gitter.im/atolab/zenoh.svg)](https://gitter.im/atolab/zenoh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse zenoh C Client API . [Eclipse zenoh](http://zenoh.io) is an extremely efficient and fault-tolerant [Named Data Networking](http://named-data.net) (NDN) protocol that is able to scale down to extremely constrainded devices and networks. . ------------------------------- ## How to install it . Work in progress... . ------------------------------- ## How to build it . 1. Make sure that [rust](https://www.rust-lang.org) is available on your platform: . -- Ubuntu -- . ```bash $ sudo apt-get install rustc ``` . -- MacOS -- . ```bash $ brew install rust ``` . 2. Clone the [source] with `git`: . ```sh git clone https://github.com/eclipse-zenoh/zenoh-c.git cd rust ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ make $ make install # on linux use **sudo** ``` . If you want to build with debug symbols set the `BUILD_TYPE=Debug` environment variable before running `make` and `make install`: . ```bash $ cd /path/to/zenoh-c $ export BUILD_TYPE=Debug $ make $ make install # on linux use **sudo** ``` . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ make examples ``` . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/zn_sub ``` . ```bash $ ./target/release/examples/zn_pub ``` . ### Eval and Query Example ```bash $ ./target/release/examples/zn_eval ``` . ```bash $ ./target/release/examples/zn_query ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/zn_sub_thgr ``` . ```bash $ ./target/release/examples/zn_pub_thgr ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 53 Depends: libzenohc (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/libzenohc-dev_0.5.0~beta.9_armhf.deb Size: 14096 MD5sum: f1ef4a9542bc467704097f7a01f73a66 SHA1: 2b8b20ba08d9ab6610e146f71c07e57e191fdcd6 SHA256: fa905b635efb77b369c6a4ba80eacff8f9bc743741d7d45a48b19f9236032165 SHA512: 0c1a07890b2fa8c36a9a2f10043db2b2bb36284742412b11744b524f17b82803e714a1dccc5b43003c4687cf479ec66e5a9ee4cbbe7fb6a056a1ca052bd86981 Homepage: http://zenoh.io Description: The zenoh C client API ![zenoh banner](./zenoh-dragon.png) . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Gitter](https://badges.gitter.im/atolab/zenoh.svg)](https://gitter.im/atolab/zenoh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse zenoh C Client API . [Eclipse zenoh](http://zenoh.io) is an extremely efficient and fault-tolerant [Named Data Networking](http://named-data.net) (NDN) protocol that is able to scale down to extremely constrainded devices and networks. . ------------------------------- ## How to install it . Work in progress... . ------------------------------- ## How to build it . 1. Make sure that [rust](https://www.rust-lang.org) is available on your platform: . -- Ubuntu -- . ```bash $ sudo apt-get install rustc ``` . -- MacOS -- . ```bash $ brew install rust ``` . 2. Clone the [source] with `git`: . ```sh git clone https://github.com/eclipse-zenoh/zenoh-c.git cd rust ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ make $ make install # on linux use **sudo** ``` . If you want to build with debug symbols set the `BUILD_TYPE=Debug` environment variable before running `make` and `make install`: . ```bash $ cd /path/to/zenoh-c $ export BUILD_TYPE=Debug $ make $ make install # on linux use **sudo** ``` . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ make examples ``` . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/zn_sub ``` . ```bash $ ./target/release/examples/zn_pub ``` . ### Eval and Query Example ```bash $ ./target/release/examples/zn_eval ``` . ```bash $ ./target/release/examples/zn_query ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/zn_sub_thgr ``` . ```bash $ ./target/release/examples/zn_pub_thgr ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8340 Depends: libc6 (>= 2.18) Filename: ./0.5.0-beta.9/libzenohc_0.5.0~beta.9_amd64.deb Size: 2247308 MD5sum: 0d221b2bffc3bbf3cb177f223b20347c SHA1: a9bdf1ed852365cdbbf97629a7d8c2241f87bca4 SHA256: 78bf7173c0b69a3d22cac559009b66bf257f1b272c220e17f45fd8be34b43062 SHA512: d686ae7cba5d9c91beb3e52efced13a30f2967a21ca08937cca6de674f41bfb25939079ca9b36bd076b1bcd56935f515999d80f38562bb40b6e4ae0c37e83bf5 Homepage: http://zenoh.io Description: The zenoh C client API ![zenoh banner](./zenoh-dragon.png) . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Gitter](https://badges.gitter.im/atolab/zenoh.svg)](https://gitter.im/atolab/zenoh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse zenoh C Client API . [Eclipse zenoh](http://zenoh.io) is an extremely efficient and fault-tolerant [Named Data Networking](http://named-data.net) (NDN) protocol that is able to scale down to extremely constrainded devices and networks. . ------------------------------- ## How to install it . Work in progress... . ------------------------------- ## How to build it . 1. Make sure that [rust](https://www.rust-lang.org) is available on your platform: . -- Ubuntu -- . ```bash $ sudo apt-get install rustc ``` . -- MacOS -- . ```bash $ brew install rust ``` . 2. Clone the [source] with `git`: . ```sh git clone https://github.com/eclipse-zenoh/zenoh-c.git cd rust ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ make $ make install # on linux use **sudo** ``` . If you want to build with debug symbols set the `BUILD_TYPE=Debug` environment variable before running `make` and `make install`: . ```bash $ cd /path/to/zenoh-c $ export BUILD_TYPE=Debug $ make $ make install # on linux use **sudo** ``` . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ make examples ``` . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/zn_sub ``` . ```bash $ ./target/release/examples/zn_pub ``` . ### Eval and Query Example ```bash $ ./target/release/examples/zn_eval ``` . ```bash $ ./target/release/examples/zn_query ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/zn_sub_thgr ``` . ```bash $ ./target/release/examples/zn_pub_thgr ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7257 Filename: ./0.5.0-beta.9/libzenohc_0.5.0~beta.9_arm64.deb Size: 1941940 MD5sum: c414bf261d5ebcdd98cfe84060818210 SHA1: 91372f8f5c1b5af9cab0a437d8dc15f430cbfd10 SHA256: c72357358ded196921fcb1843a5a9dd740e0bad883f955ab0f9230632f07fba2 SHA512: efeba4e90232966d4b318656feb3b5edaebaf0b79443fb51460da02a3e59f4ed517382c8d21a2d3f75e7b92b2cac5cae2ec88c05b40b0aaa5469f8c6664afa1a Homepage: http://zenoh.io Description: The zenoh C client API ![zenoh banner](./zenoh-dragon.png) . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Gitter](https://badges.gitter.im/atolab/zenoh.svg)](https://gitter.im/atolab/zenoh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse zenoh C Client API . [Eclipse zenoh](http://zenoh.io) is an extremely efficient and fault-tolerant [Named Data Networking](http://named-data.net) (NDN) protocol that is able to scale down to extremely constrainded devices and networks. . ------------------------------- ## How to install it . Work in progress... . ------------------------------- ## How to build it . 1. Make sure that [rust](https://www.rust-lang.org) is available on your platform: . -- Ubuntu -- . ```bash $ sudo apt-get install rustc ``` . -- MacOS -- . ```bash $ brew install rust ``` . 2. Clone the [source] with `git`: . ```sh git clone https://github.com/eclipse-zenoh/zenoh-c.git cd rust ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ make $ make install # on linux use **sudo** ``` . If you want to build with debug symbols set the `BUILD_TYPE=Debug` environment variable before running `make` and `make install`: . ```bash $ cd /path/to/zenoh-c $ export BUILD_TYPE=Debug $ make $ make install # on linux use **sudo** ``` . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ make examples ``` . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/zn_sub ``` . ```bash $ ./target/release/examples/zn_pub ``` . ### Eval and Query Example ```bash $ ./target/release/examples/zn_eval ``` . ```bash $ ./target/release/examples/zn_query ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/zn_sub_thgr ``` . ```bash $ ./target/release/examples/zn_pub_thgr ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7603 Filename: ./0.5.0-beta.9/libzenohc_0.5.0~beta.9_armel.deb Size: 2070740 MD5sum: 6230f3eab5ab0f49607e45034930f52a SHA1: 35fcd5f2cedd9afd5ddd6a29d8f266fb64c69e56 SHA256: 338e0aaba11be9dbbffe51edadb86aca068fd24d8adbb4461aeb71239d837b33 SHA512: 7c15b0f1e5bb5d1e6d3407476f81aff0400870aaf71216cd656b79842f2d1fb2774d9e41450d43d13b8371a731f3793e3cf8db8df0cc10cdb0ae97913d3ba67c Homepage: http://zenoh.io Description: The zenoh C client API ![zenoh banner](./zenoh-dragon.png) . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Gitter](https://badges.gitter.im/atolab/zenoh.svg)](https://gitter.im/atolab/zenoh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . . # Eclipse zenoh C Client API . [Eclipse zenoh](http://zenoh.io) is an extremely efficient and fault-tolerant [Named Data Networking](http://named-data.net) (NDN) protocol that is able to scale down to extremely constrainded devices and networks. . ------------------------------- ## How to install it . Work in progress... . ------------------------------- ## How to build it . 1. Make sure that [rust](https://www.rust-lang.org) is available on your platform: . -- Ubuntu -- . ```bash $ sudo apt-get install rustc ``` . -- MacOS -- . ```bash $ brew install rust ``` . 2. Clone the [source] with `git`: . ```sh git clone https://github.com/eclipse-zenoh/zenoh-c.git cd rust ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ make $ make install # on linux use **sudo** ``` . If you want to build with debug symbols set the `BUILD_TYPE=Debug` environment variable before running `make` and `make install`: . ```bash $ cd /path/to/zenoh-c $ export BUILD_TYPE=Debug $ make $ make install # on linux use **sudo** ``` . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ make examples ``` . ## Running the Examples . ### Basic Pub/Sub Example ```bash $ ./target/release/examples/zn_sub ``` . ```bash $ ./target/release/examples/zn_pub ``` . ### Eval and Query Example ```bash $ ./target/release/examples/zn_eval ``` . ```bash $ ./target/release/examples/zn_query ``` . ## Running the Throughput Examples ```bash $ ./target/release/examples/zn_sub_thgr ``` . ```bash $ ./target/release/examples/zn_pub_thgr ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7513 Filename: ./0.5.0-beta.9/libzenohc_0.5.0~beta.9_armhf.deb Size: 2077076 MD5sum: c24f702e855f148083ae97690956ec2a SHA1: 1307de4f1fe7c3b6e4bf08f7cd385f48d289226e SHA256: 310c8bf296da7b2d600193e86ee523f7a470cb3c5817c37df3598ad0153ea7ec SHA512: 7fb3db2c0672bdc821c0a86dc528c8bd5379c596580b204e038604757531864aa171a919594c665d9b24d40b41e75f96a9cc0c0ecdbc65569d30bb702e6a28bf Homepage: http://zenoh.io Description: The zenoh C client API ![zenoh banner](./zenoh-dragon.png) . [![CI](https://github.com/eclipse-zenoh/zenoh-c/workflows/CI/badge.svg)](https://github.com/eclipse-zenoh/zenoh-c/actions?query=workflow%3A%22CI%22) [![Documentation Status](https://readthedocs.org/projects/zenoh-c/badge/?version=latest)](https://zenoh-c.readthedocs.io/en/latest/?badge=latest) [![Gitter](https://badges.gitter.im/atolab/zenoh.svg)](https://gitter.im/atolab/zenoh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![License](https://img.shields.io/badge/Licens