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/License-EPL%202.0-blue)](https://choosealicense.com/licenses/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: libzenohpico-dev Architecture: amd64 Version: 0.5.20211126dev Priority: optional Section: devel Maintainer: ADLINK zenoh team, Installed-Size: 197 Depends: libzenohpico (=0.5.20211126dev) Filename: ./0.5.0-beta.9/libzenohpico-dev_0.5.20211126dev_amd64.deb Size: 24490 MD5sum: f7f136c2d5c72e3874da542580871ec7 SHA1: a04face863db79cbdc12525d136537478b10f0b9 SHA256: 0eb12d5ede695b75b7f172466ee4f366035143bf29353bb492f0fb4be1878cf4 SHA512: 7790f1aa7627df29fdc12e975833d63c7a2b4766257d53b2e56ddd10d6db6b52b3e270bfb0d912a5a69e3b12ae5417017f4bed8c3b668c5ed3bec7d9c71a0ffa Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: arm Version: 0.5.20211126dev Priority: optional Section: devel Maintainer: ADLINK zenoh team, Installed-Size: 197 Depends: libzenohpico (=0.5.20211126dev) Filename: ./0.5.0-beta.9/libzenohpico-dev_0.5.20211126dev_arm.deb Size: 24482 MD5sum: 2eb796ca3a8133243064f2a6ddec0cc2 SHA1: 1a2c9805ef9043253ee5e6ce64237c1cb1eb71fb SHA256: 1819356cf4417d9f0297fe2fdf434b1513dd84267265829c2ad0c3769e57587c SHA512: 22e506bf3199fc81e102e20c83c9cf4655ca186e5c76a8e5c6ebc970e9a64c3f40a224cc8d24b5ebc3b2918fc90a54963838e4b22acc6fa8a77f3df30eea4d96 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: arm64 Version: 0.5.20211126dev Priority: optional Section: devel Maintainer: ADLINK zenoh team, Installed-Size: 197 Depends: libzenohpico (=0.5.20211126dev) Filename: ./0.5.0-beta.9/libzenohpico-dev_0.5.20211126dev_arm64.deb Size: 24490 MD5sum: 62b7ad74136d8b50ce0ef95a7f1427e6 SHA1: d980aed79be70e8b2f7c8ba301d63f1ca6bfc572 SHA256: 87ced0579a53ef46f915c4373601d6a59113a39c25e110ebd9e2703955a090f6 SHA512: 6d33064d3414801a0b9d2eba3d944007fb209f311c7a20c1634d13e7e63aa620da43ac166059afbb3b20ad037cd8fb22e1c8800d27ba2b3cf9d347cd8cd91872 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: armhf Version: 0.5.20211126dev Priority: optional Section: devel Maintainer: ADLINK zenoh team, Installed-Size: 197 Depends: libzenohpico (=0.5.20211126dev) Filename: ./0.5.0-beta.9/libzenohpico-dev_0.5.20211126dev_armhf.deb Size: 24486 MD5sum: 045417998848225829482437eee0e684 SHA1: 12f4c9c0b3a2d77d2ac4dd358b7607602853c24d SHA256: d23a768c11dd91347b8a85f41853eb069ed1c14f690c0252b20ca396e6d72dbb SHA512: 24a844503a7343715c5280627503993ee300c198ca7ced8171406aba92be093f9b856d53f30e048247c11096eb2155a0339ba9005ef7bb7e8e3c476c0fa4d0a6 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: i386 Version: 0.5.20211126dev Priority: optional Section: devel Maintainer: ADLINK zenoh team, Installed-Size: 197 Depends: libzenohpico (=0.5.20211126dev) Filename: ./0.5.0-beta.9/libzenohpico-dev_0.5.20211126dev_i386.deb Size: 24486 MD5sum: dd6374daf34a47a766fd64f8d1c4fd19 SHA1: e76842ec1bf1761546cb8c9db25fed2f59584057 SHA256: cda90fe99b40e9a0904437598bc51eb1dc53c7c0311fabbf70d851a4a3b8a1e7 SHA512: e8f96e00fef68f44fc2861a8a92f6cd42d7e1c6d7bcea32aecd95224d22472f704036be746a27050966547cec5b70f159d9c6d54af747c395e0fd585c082035d Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: mips Version: 0.5.20211126dev Priority: optional Section: devel Maintainer: ADLINK zenoh team, Installed-Size: 197 Depends: libzenohpico (=0.5.20211126dev) Filename: ./0.5.0-beta.9/libzenohpico-dev_0.5.20211126dev_mips.deb Size: 24488 MD5sum: 9257551d8ed5df86c573835269a46eed SHA1: b8d4a0bf73704f76b5f64709b334a5144a2a1567 SHA256: a0dd1ac62afaf9a8b26cc378024a1ac49868bd2bb52a52f0361e835dd58e6b9f SHA512: 6cd7977a60d1a256ab39e449dd01b060a6be5faa5219394b934c36744fb76db8ea3ad385347f8ae818922d8546e2de64fd6ea06d22a458cde526c1f048438425 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico Architecture: amd64 Version: 0.5.20211126dev Priority: optional Section: devel Maintainer: ADLINK zenoh team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.5.0-beta.9/libzenohpico_0.5.20211126dev_amd64.deb Size: 610 MD5sum: 3c9c7735c953dbb6df2f8bcfe0580bff SHA1: 4c848228635526d8e9778d23519aa6d715623a24 SHA256: cc500af6f40396ac2dd60c5f33c5d76b2cba588b86d5e97308eab43be354a81c SHA512: 7bf8f1220a21a826408c2488aa0c13c5d852c68ae00ed133b7e8eaf95729c5a9b82f16e67c7ee6dd5ae3c1aefb705996f77dfcbccc4898236bf2535469ff1c13 Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: arm Version: 0.5.20211126dev Priority: optional Section: devel Maintainer: ADLINK zenoh team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.5.0-beta.9/libzenohpico_0.5.20211126dev_arm.deb Size: 606 MD5sum: 921d367d9f325bf848223740ce14df6d SHA1: 0b0b1824abf9dc59c5049abb2d542268bfe40f97 SHA256: ae5d8c5957d26dee4242d80aadb59f6ed15fe9a0031476f4fdb534c631dbcd68 SHA512: 57efef295e95c4bf6a839140295c0e1768b8cea4e672fd1608d873bf6d69c3b553eef8bac3436e8e4f109c170d377159319217324be392a402b4872da1332cab Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: arm64 Version: 0.5.20211126dev Priority: optional Section: devel Maintainer: ADLINK zenoh team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.5.0-beta.9/libzenohpico_0.5.20211126dev_arm64.deb Size: 612 MD5sum: 076ad8328b12abf8e28f094c929f18ef SHA1: 17abfe6d34b1321c380a407b2c90ad197a46c10c SHA256: 15376192b4a16894de331974e8859dc88004adfd6013a0ea153e8ca1a9004539 SHA512: 7f1ac977feed43f692150ca77b68e08474d860c9588c29b0ad37bf9469c0070104445252cca999889f6ac9b43d29fab546cd83d7d47e955c0e40ad78a38d4ddf Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: armhf Version: 0.5.20211126dev Priority: optional Section: devel Maintainer: ADLINK zenoh team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.5.0-beta.9/libzenohpico_0.5.20211126dev_armhf.deb Size: 610 MD5sum: 542c0334e7b9885d1857ce085993ac01 SHA1: 344dc7462759aaec8a555c7f99c921e9db3cc54d SHA256: af2597f795f9186d05412b069cab513021cd7699cf6bbfd8ddc3b58083c3dbcb SHA512: 045839c24c2779cf2195785612571db4fa830d4b8b9d8e4d236dbf9f5d756bbe3e8be3dbd7e24ebb475991ec5ee9f628e62d3d76d1d001b63d9a19e3a77fb924 Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: i386 Version: 0.5.20211126dev Priority: optional Section: devel Maintainer: ADLINK zenoh team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.5.0-beta.9/libzenohpico_0.5.20211126dev_i386.deb Size: 608 MD5sum: bf7bd79e9021187706633f5a5e6218bb SHA1: db8469294eae733b813e39670a1f747dc4a6033e SHA256: 2e747619fc2aa355fe7f0ffd0a8e074f819a7f52f297e125d1ccbe4976bcf6b7 SHA512: d5302e8cbc4cbd4e03daf356908c8add2215f40592b16705ff53b8b1252be41620c83db7fdc5a0ff3a435ba615360929f3c21a9e3c0a949346a4406e20dbf0e3 Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: mips Version: 0.5.20211126dev Priority: optional Section: devel Maintainer: ADLINK zenoh team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.5.0-beta.9/libzenohpico_0.5.20211126dev_mips.deb Size: 608 MD5sum: 2b35a57f846f449b3ab6eb3bfca914b2 SHA1: ff2cb8792ed1c5834e6f558702160b4cc0b499b3 SHA256: b131871220f95e85c79a35a110be56530abf4a215449fb12273ff1957b918335 SHA512: bf8a7f69408ea2e4f8c839e3fd2cbd0897301b1b7771848b3a322d8319610e2a5062034684d4526412f57a6f1223bce6f69b6e93b59f889fc01b0f8204f8e32f Description: The C client library for Eclipse zenoh targeting pico devices Package: zenoh-backend-filesystem Architecture: amd64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7553 Depends: zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-backend-filesystem_0.5.0~beta.9_amd64.deb Size: 2353972 MD5sum: b005e0d1ebc7a7060f5455a5a044f6c5 SHA1: ab366d67b262d79231d0f2fbe08472ba873e9f1d SHA256: e4c079c82983249d10aee4aa1a475cffa086216ae0075e83299d2e07acc60f17 SHA512: 053e1d53f822ecefb8e172260cd705b05edb6aa94031344b2034d970d25ff39646ad089407f128bb66c539f171782e88e4b10c861bf1d418daeb99eafba796c0 Description: [generated from Rust crate zenoh_backend_filesystem] Package: zenoh-backend-filesystem Architecture: arm64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6466 Depends: zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-backend-filesystem_0.5.0~beta.9_arm64.deb Size: 1953720 MD5sum: eb1a045393a5212e4f90cd60dc6440ee SHA1: 95dbbe24bf34cd42d1ce61694a7345bcc071dee1 SHA256: fc55ecd48730670d2d9d0f46ca3bd75298b4777e54d08ad68df0019706b67dd6 SHA512: 9b12139a092c9939da0a173740bfcb930bc3a600604826bb63bdd4c69d67524401fef0bb9879544b53d24f52c2d14f4cf8fcd84e763629272c0e2a7cb806e3d7 Description: [generated from Rust crate zenoh_backend_filesystem] Package: zenoh-backend-filesystem Architecture: armel Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5964 Depends: zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-backend-filesystem_0.5.0~beta.9_armel.deb Size: 1910044 MD5sum: 5e67d8b389d9b35543b8f93752787a52 SHA1: b492a8ad88e3fc93fddf7c0e90d6ab9ebe7f5c05 SHA256: 60874560fd56827b7206a5384570d783e94fcb5004bd2d1ac0e9117f7ead28a6 SHA512: b6cf8fb8e1a781dc47e96ea89cd40d79b63f861a5d9bcb2d06ca459afa4fdcba311832b677b77a51105823d6b9651c6a3cf25005ff291b558aecd677ff32b1a9 Description: [generated from Rust crate zenoh_backend_filesystem] Package: zenoh-backend-filesystem Architecture: armhf Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4836 Depends: zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-backend-filesystem_0.5.0~beta.9_armhf.deb Size: 1973400 MD5sum: b53c8cd47b0ac92c7448ea5aee856cdf SHA1: 2141f92b8049d132ba7de81e3db06595d2b887b2 SHA256: 9cff3b684902fca13b51b5115d19337825e5e9065792f458bef1277f5a876ed7 SHA512: 04ca3fbd05ab71c8fdc79bf2793e11a1e18d4df1d7eb7ab48a0f147b652848ccaa77888952401385c44669dce6388b1c5e98a1a5731bc6114ca9c2d4daaa0bce Description: [generated from Rust crate zenoh_backend_filesystem] Package: zenoh-backend-influxdb Architecture: amd64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4893 Depends: zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-backend-influxdb_0.5.0~beta.9_amd64.deb Size: 1482996 MD5sum: e40a2845c4f673af322ba47d88442d22 SHA1: 77d4f9cc319098b61f6f81a1e50661e06af16776 SHA256: b595adb8e1565272fe9fc1d35f23d12ce8fba6ef672d29613626ede853684ff2 SHA512: 6819fa6efe2fe11007d1dac9b44f891d49df9318b4a561f9751c58a5493ab306b3e5a5fcbb5a79e9d974cbd7281d3ceed3fdf98eb38a962528f6a0c8c0525bfc Description: [generated from Rust crate zenoh_backend_influxdb] Package: zenoh-backend-influxdb Architecture: arm64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4325 Depends: zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-backend-influxdb_0.5.0~beta.9_arm64.deb Size: 1265752 MD5sum: 99b79ead622eac4008daed5c8a7f0f07 SHA1: 79712143c2d0a9045212da112ad00512a4623b80 SHA256: 09a1dac447ed04a70d6399b55592c5925a5fabde0c25f0e20e521be8317d67de SHA512: 75573f68098c763f05551bb1ebb746ad6dfc5c9a56ee174c4260cc57990045e87705ba39d3a2810b1ebcfc9b81c89bd11e4a8c0519db1a0c77df37354c731781 Description: [generated from Rust crate zenoh_backend_influxdb] Package: zenoh-backend-influxdb Architecture: armel Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3852 Depends: zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-backend-influxdb_0.5.0~beta.9_armel.deb Size: 1135108 MD5sum: e74df87a44b0c440687aec14a6bf8adb SHA1: aad905517eae0a5407a3cec643c225452c259d81 SHA256: d96577a780d12bb2be61074a1e817867213f9aa2db310447f3319e776c827ea1 SHA512: e219bb6d1b065ba27012a2d2564975e4aafb4bb2eef19af0f93b41b96809bd7d92975e80ed61fcfc40498676dc9aec8702e4f1fd57e4e42c4919eed79ffb84a4 Description: [generated from Rust crate zenoh_backend_influxdb] Package: zenoh-backend-influxdb Architecture: armhf Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3764 Depends: zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-backend-influxdb_0.5.0~beta.9_armhf.deb Size: 1135788 MD5sum: 587ddee74a8f90f5be95af7cbba87931 SHA1: 87fa52a7adc5a15d63c61ecbef9fc162a63828d4 SHA256: 8aaf8cc2504de297345bb7d864593de3ef4c4d578c06c1ac49f99f494069d12f SHA512: 6166ade5455158996d39e6048e6540e9afdd3a8a95de208b4dc86b134ce56f5abef9a2c4f2ef9f6cf8d686cfcb40d6f6bdb97c3a45d683aa03441cbbaa3d9bb4 Description: [generated from Rust crate zenoh_backend_influxdb] Package: zenoh-backend-rocksdb Architecture: amd64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7441 Depends: zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-backend-rocksdb_0.5.0~beta.9_amd64.deb Size: 2338580 MD5sum: 9d7f5bff0580ee2d498fbd96ff2500bf SHA1: e35533af2edd36c251503f9525f45732730c730e SHA256: ef4df75f619596ad8d7d1d34b3c48c9ce623c97fa8a16ad85936f519ed6dc6bd SHA512: 88f5ad176c5af828975dfd5c14e33b781826f901282256b591a752b02119ac581ffcf4d21441330c861cb9f62b3c6b351ed6a06e13520151deee953a5e097fdf Description: [generated from Rust crate zenoh_backend_rocksdb] Package: zenoh-backend-rocksdb Architecture: arm64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6370 Depends: zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-backend-rocksdb_0.5.0~beta.9_arm64.deb Size: 1941992 MD5sum: a3dc98675a9029e49f85bad6c8948ab3 SHA1: ccf7c42bee3c82389ae33522e2752d94de076ed2 SHA256: c57b788b0599b17198ff0391218e02e2c25eeb61929bccb7055bfc905c29c4c4 SHA512: 13fc9174c77d3080f2826871a3890e4cf795e222db25aad5577826f8f3d61b33690a3adcf4cde20de40ffc9978b28ce9e9af6cd1ed55bb2f9bb0d69dcc20b515 Description: [generated from Rust crate zenoh_backend_rocksdb] Package: zenoh-backend-rocksdb Architecture: armel Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5928 Depends: zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-backend-rocksdb_0.5.0~beta.9_armel.deb Size: 1903136 MD5sum: 60dbb167520b332661e0a681646ea6fa SHA1: d5e275768e2def82254478e30792b70f67222664 SHA256: 81af58eddb814ece0094e69108c0d00685c88acb404c280bab4c10ba6fdb064b SHA512: 6191e823f5ee21a1b4ec1df27222e8d6e8bf875ac89ec9eeb72cd06946e4be957f4937ea8776717f74d3f0505aa4a8ad0f25663ee0434887a47c93b03484abfc Description: [generated from Rust crate zenoh_backend_rocksdb] Package: zenoh-backend-rocksdb Architecture: armhf Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4764 Depends: zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-backend-rocksdb_0.5.0~beta.9_armhf.deb Size: 1965624 MD5sum: 9265ac619766d07c2a6849dcad03b077 SHA1: 7cd6e78f8dcaa1aa719e40e9010440e25b0f61d6 SHA256: d2d3457c5335b7efa0210ecaa320d48c5340fd026bbdae6a84ff7758e33a3050 SHA512: cee83ebe0b4c5398aeaa4fe254a4928fd940c737ff78e7df4596c63129aa1e6f45b89253cac4a3af1fac48a7794379bc5740e9d9895dfa66404100f69d878060 Description: [generated from Rust crate zenoh_backend_rocksdb] Package: zenoh-plugin-rest Architecture: amd64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3401 Depends: zenohd (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-plugin-rest_0.5.0~beta.9_amd64.deb Size: 943408 MD5sum: 982b0fbdeb771599932e833e58f8b5e2 SHA1: 6273d397296d2913a2034a3a1957bf15f9bb4d66 SHA256: a4c07d344b4c4c3621550b43cd90122827283db26f63aafe132ba022dcfc2386 SHA512: 701c8e2db9b1c79de113b8deb0f284e93961b7fc68f36282234bf4ea341614341384c829a6d6f4614c65dece5bf5f5d8b75a6f91d34a80b9e09f20d2a9ea3e25 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-plugin-rest Architecture: arm64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3025 Depends: zenohd (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-plugin-rest_0.5.0~beta.9_arm64.deb Size: 794012 MD5sum: c6167dff896f11663dd9cc970a8c428c SHA1: c1bbb6901552de00c96e55dd946e5e7448dfec8d SHA256: eb38b55a0279748405fae45b5531323c453ce255b8d68e38278904ebeee1f6a6 SHA512: a8c478a9fcb1acb5c612af1cb55b79185da24c40268be9111aa8e9927e409c450ff5496ddc14a145a8832b0b61f236598db2a5fd21dddeb637ded492a80c0e15 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-plugin-rest Architecture: armel Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2847 Depends: zenohd (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-plugin-rest_0.5.0~beta.9_armel.deb Size: 839196 MD5sum: f477915769d94aff2ad5432cae99fd2d SHA1: 69174f8c29b530fb1f7c86fffa884dc7f22a2fd3 SHA256: 5dfbfff1b4f5d4d354ecf08d53e5c17bfe5b4f9a9cb811647bc1cdd6b00eb6a2 SHA512: f4568aa12f6f407ce22de0f334ba02da2789f17751922772c0842633a668074ce6f3883406a64a09c23187ca0add92cb85da32e98a972f78f8b114787e0b56bc 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-plugin-rest Architecture: armhf Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2791 Depends: zenohd (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-plugin-rest_0.5.0~beta.9_armhf.deb Size: 832916 MD5sum: b4b2ad1f9143a43067e904e7002425c6 SHA1: 805ae3ab5b1b0c15a71b4f1e62df07b482e8b736 SHA256: 3e128f2093e6609c57dd950b6f955b2ab9f5ad2a804b5a53860ea7a8f9b08d5b SHA512: b4234d6c660900ad96350c4f273b032b399d1577561da8743052778196c629fb390a49d7c1224efb485c2cefb6ba86aec31188862c5bfbbbdfa59b7e342ab59c 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-plugin-storages Architecture: amd64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2478 Depends: zenohd (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-plugin-storages_0.5.0~beta.9_amd64.deb Size: 740088 MD5sum: 927b7f1ef1a617ff020141109cc35a25 SHA1: b5d6452c92562a264e4678156b4fa9cb8bccab2f SHA256: af4cd8b28309458aca56a3e2d460d09c20c4afbaa4370802ca2d875a3b252c72 SHA512: 876e7ef54c21078c5d4c2449ff48d62872c83b7bcf279a634227bcdd29130f851897ffcbd3b8c0afb457891ef626e5290138578ba150d0906eb6197bcbd803ba 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-plugin-storages Architecture: arm64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2194 Depends: zenohd (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-plugin-storages_0.5.0~beta.9_arm64.deb Size: 629308 MD5sum: 385a6e381293f68a0667d45d028b29bf SHA1: e095f4f9bf7fa35e1245bf43ebcc3e88f4b130b1 SHA256: e549a208b0ef69ad36fa516ae8178b3000bcd68867628bc627a16b5411bc201f SHA512: ee6779830835837a8c2159993db5ed854d0d47636328e2e648700b6b24e95d0bd7dab14204f2a1bc6fbeb4511e092426b615bde946eada579a18131da3bc9c43 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-plugin-storages Architecture: armel Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2189 Depends: zenohd (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-plugin-storages_0.5.0~beta.9_armel.deb Size: 682888 MD5sum: ef1ef3ad04d27abf84c9cfff7b48a045 SHA1: de4889f250a85577129e1371795059d5dd6afd7e SHA256: 615307bbfa68e1b24df9b9d2d58487bdf692cdeb95dc1d950c5c9495502e970e SHA512: e82a26e60065aa675a91ffcc619a676c1206c2ac22d740542acd77988cfdb7867999fa68dc5a53881ae94bb688a6192d2e932837a51024f68488e5941e969f7a 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-plugin-storages Architecture: armhf Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2141 Depends: zenohd (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-plugin-storages_0.5.0~beta.9_armhf.deb Size: 678336 MD5sum: aa66321504f2033f59070f2b52b6fafc SHA1: 7645b37331efce6e57782e257b2a4f6713828737 SHA256: 5161708116c6a534f8681d540ca6d06b189b70dfb597195574ced28c56903f6c SHA512: 10e0a0947f3c0e8f4e86fd3df7951ac8b0d0b18e5c77f1b2d5e556dcc220ea6f343a16f62b4301562ba77b21c85efadf4cbd8a7409d5e75bd9db1384c27e89ac 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-plugin-webserver Architecture: amd64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4104 Depends: zenohd (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-plugin-webserver_0.5.0~beta.9_amd64.deb Size: 1087764 MD5sum: 0dd0ab23ede490c53e3729843573e661 SHA1: 24557ec6c3a304dca23b30afa43d6d6a11576a11 SHA256: 5fa2bfe1e1b5f14094c54a107213e1a6e5b8fc5db7ff8a6f2026de91b6b00887 SHA512: 0399c49189967fca95a1e849f9a565019af4384c738c59de6ad156737df1172620cc9f8234e70f9f13cf15f0d052001b7717b8e2f68fb0c975832d396395bdaa Description: [generated from Rust crate zenoh_plugin_webserver] Package: zenoh-plugin-webserver Architecture: arm64 Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3760 Depends: zenohd (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-plugin-webserver_0.5.0~beta.9_arm64.deb Size: 911220 MD5sum: 2602acb2b0c74646016f7904acfb368e SHA1: b51b15874557eaa24aaa99d18b3987ea7145646c SHA256: 9077b9d8f02fa64f53ce227b8f50c674ab78c1d1c8e4465f46f44db6e1fb8aae SHA512: a6e6a8666ea9c12b44f00c11f4eb0ddbe303b4b529ae809c8e64e2408ab3a703851fc358342e8dad1bd63b19cc50782f6a538410aa07d03caea191b8a3ae3b83 Description: [generated from Rust crate zenoh_plugin_webserver] Package: zenoh-plugin-webserver Architecture: armel Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3414 Depends: zenohd (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-plugin-webserver_0.5.0~beta.9_armel.deb Size: 920764 MD5sum: 9728c823598a1f1765356bc2b3c4ff01 SHA1: d382b390156ec5a6a0ac20b9a61af3f1e1229325 SHA256: 11903ea053886740c4b10937df323984368ac7254589d82b8c25ed4416dbcba3 SHA512: 5383c7d1f15554192c7f0f62b78cf32aed95d024c65ac5dc476b3283fd369356f0bffd8953fa707195124a5971b764fc03003161852f110b08b0adc840b8a139 Description: [generated from Rust crate zenoh_plugin_webserver] Package: zenoh-plugin-webserver Architecture: armhf Version: 0.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3330 Depends: zenohd (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh-plugin-webserver_0.5.0~beta.9_armhf.deb Size: 910172 MD5sum: ea8556873fcb3dbc52db75187815747d SHA1: d05c79b736f604e88c8ccd0297bd998ec8721ea7 SHA256: 575b20a6a7e431cb2e3cb05528d0f98c1f6f3e0982f05d3db3f2e9d05e64c408 SHA512: ed0681b60bda1185496bbf60dffb02c103ea286cb6753f0a44f45bb0daf31b30521981d6d152abd91dcce7eb53b6e5957d68b48697f50774a5434e3a78518904 Description: [generated from Rust crate zenoh_plugin_webserver] Package: zenoh Architecture: amd64 Version: 0.5.0~beta.9 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.5.0~beta.9), zenoh-plugin-rest (=0.5.0~beta.9), zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh_0.5.0~beta.9_amd64.deb Size: 828 MD5sum: 5882ab6d00c8728a5ceb2cc900ab333b SHA1: 6d0f2b73edb56aa57d8b9be9046deff440c1c973 SHA256: 786f7cad7ce586f6cbdfed0de7b94ad565c9a1659a7ee5a879599398975a632c SHA512: 898d895edfcb15211a338cbd745004e66e5f269a9afe390f2e01418c121ac2f88139ea1030aacdf3dbec825cb63f68b38613e50f39fb233f1254f19654e15890 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.5.0~beta.9 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.5.0~beta.9), zenoh-plugin-rest (=0.5.0~beta.9), zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh_0.5.0~beta.9_arm64.deb Size: 828 MD5sum: 343ebbef8a3bb4065855662334a230ad SHA1: 37f2d3b251d89c93298a033007c7ecb57efe06d0 SHA256: 5e81d24d06cf6318a72e97d1825e17fc7846d82828948c9596da2e50487010ce SHA512: fb2b58cd7f0e5a0102349eaf5e7cd01b8c3d00b24f18b491baced351229d20df2d8429f0777396ea4fe68eab61157b1502f374f6476ab082531fd944546da7a4 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.5.0~beta.9 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.5.0~beta.9), zenoh-plugin-rest (=0.5.0~beta.9), zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh_0.5.0~beta.9_armel.deb Size: 828 MD5sum: 8de9a6e55cd8357914f6767974a37e9c SHA1: 4ccf2d77e822428ae57e3842da8d484a3b2f0c58 SHA256: 988aa0341b2952f6a03518ca1ffa36dfc654da1a9a3d80c10065ad500f79ca3c SHA512: 1941c8f9bf48a028833caeb7572f959d38e5c4b5852a324ba6e2a42dd8b7bc5711b0b474b49d680f871774ff9800c38ff40e15b9bee5702d2404ab02fde5b12a 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.9 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.5.0~beta.9), zenoh-plugin-rest (=0.5.0~beta.9), zenoh-plugin-storages (=0.5.0~beta.9) Filename: ./0.5.0-beta.9/zenoh_0.5.0~beta.9_armhf.deb Size: 824 MD5sum: 50690e05bc1fa670b9dde1d1eb6bb54d SHA1: 9f1e2519e623ff66e53a3d9080427e311d6fce76 SHA256: c3fe30006f957021004d29c1db1ed532ef562d5e1aff5e570307a76da0501a8b SHA512: 74eebc627eb6ec3a82f5b29d2f5bba937b4d40c04eb6cec15284481f03509588450af5fc9b644813b5ab68c3bd7349a329c907cfd6f3d3bacb7c53dabdee3f46 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.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5331 Depends: libc6 (>= 2.18) Filename: ./0.5.0-beta.9/zenohd_0.5.0~beta.9_amd64.deb Size: 1748672 MD5sum: 3799b6000804f47774bce4138d3b719e SHA1: b976047b0dfb6936bf874acc38fb6ab35d9e0042 SHA256: 38a190e31d7b64011af2f319e69bb2ef8b87ee314d7760ec092eb4fa8b4d2a26 SHA512: e6d4a14b47e82891f83e8401977fa3d3cea4cef245e362ce7fcda1e6678f1f2485a1620caa08661538aa08d2f61901695a21889fadf095fd7c08568063e89f6b 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) [![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 (pronounce _/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 install and test it . See our _"Getting started"_ tour starting with the [zenoh key concepts](https://zenoh.io/docs/getting-started/key-concepts/). . ------------------------------- ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.5.1), so no special configuration is required from your side. To build zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . The zenoh 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/eval** - run: `./target/release/examples/z_eval` - in another shell run: `./target/release/examples/z_get` - the eval should display the log in it's listener, and the get should receive the eval result. . **Routed tests:** . - **put/store/get** - run the zenoh router with a memory storage: `./target/release/zenohd --mem-storage '/demo/example/**'` - 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 --mem-storage '/demo/example/**'` - 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 a memory storage: `./target/release/zenohd --mem-storage '/demo/example/**'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the backends of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/backend/*'` - 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/**/storage/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/properties' -d 'path_expr=/demo/mystore/**' http://localhost:8000/@/router/local/plugin/storages/backend/memory/storage/my-storage` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storage/*'` . . See other examples of zenoh usage: - with the zenoh API in [zenoh/examples/zenoh](https://github.com/eclipse-zenoh/zenoh/tree/master/zenoh/examples/zenoh) - with the zenoh-net API in [zenoh/examples/zenoh-net](https://github.com/eclipse-zenoh/zenoh/tree/master/zenoh/examples/zenoh-net) . ------------------------------- ## zenoh router command line arguments `zenohd` accepts the following arguments: . * `-c, --config `: a configuration file containing a list of properties with format `=` (1 per-line). The accepted property keys are the same than accepted by the zenoh API and are documented [here](https://docs.rs/zenoh/0.5.0-beta.8/zenoh/net/config/index.html). * `-l, --listener ...`: A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default `tcp/0.0.0.0:7447` is used. The following locators 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, --peer ...`: A peer locator this router will try to connect to. Repeat this option to connect to several peers. * `--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.: 0A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random UUIDv4 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. * `--plugin-nolookup`: When set, zenohd will not look for plugins nor try to load any [plugin](https://zenoh.io/docs/manual/plugins/) except the ones explicitely configured with -P or --plugin. * `-P, --plugin ...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. 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:.'` . By default the zenoh router is delivered or built with 2 plugins that will be loaded at start-up. Each accepts some extra command line arguments: . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): * `--rest-http-port `: The REST plugin's http port [default: 8000] . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) . * `--no-backend`: If true, no backend (and thus no storage) are created at startup. If false (default) the Memory backend it present at startup. * `--mem-storage ...`: A memory storage to be created at start-up. Repeat this option to created several storages * `--backend-search-dir ...`: A directory where to search for backends libraries to load. Repeat this option to specify several search directories'. By default, the backends libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` . ------------------------------- ## 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 Gitter channel](https://gitter.im/atolab/zenoh), 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.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4563 Filename: ./0.5.0-beta.9/zenohd_0.5.0~beta.9_arm64.deb Size: 1521596 MD5sum: 50fc69d5197c681e562fb0516afb2f17 SHA1: 3439e95e276226edcfd370d1a3fd9b2e17e0be80 SHA256: c12a4a2b1c252ad51beb8a9b71ed116cf00f63f4c25d5e5a1c23d689e7b3a7dd SHA512: d89a97c8cd9dbbeaf8609a0a4eace5d8ae58a93b2a281dbbf032141d19d9a87073e7fa5502da6d747508924b4f1a2f9cd3d5735eb8b3a906e04e50eecf414e39 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) [![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 (pronounce _/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 install and test it . See our _"Getting started"_ tour starting with the [zenoh key concepts](https://zenoh.io/docs/getting-started/key-concepts/). . ------------------------------- ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.5.1), so no special configuration is required from your side. To build zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . The zenoh 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/eval** - run: `./target/release/examples/z_eval` - in another shell run: `./target/release/examples/z_get` - the eval should display the log in it's listener, and the get should receive the eval result. . **Routed tests:** . - **put/store/get** - run the zenoh router with a memory storage: `./target/release/zenohd --mem-storage '/demo/example/**'` - 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 --mem-storage '/demo/example/**'` - 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 a memory storage: `./target/release/zenohd --mem-storage '/demo/example/**'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the backends of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/backend/*'` - 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/**/storage/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/properties' -d 'path_expr=/demo/mystore/**' http://localhost:8000/@/router/local/plugin/storages/backend/memory/storage/my-storage` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storage/*'` . . See other examples of zenoh usage: - with the zenoh API in [zenoh/examples/zenoh](https://github.com/eclipse-zenoh/zenoh/tree/master/zenoh/examples/zenoh) - with the zenoh-net API in [zenoh/examples/zenoh-net](https://github.com/eclipse-zenoh/zenoh/tree/master/zenoh/examples/zenoh-net) . ------------------------------- ## zenoh router command line arguments `zenohd` accepts the following arguments: . * `-c, --config `: a configuration file containing a list of properties with format `=` (1 per-line). The accepted property keys are the same than accepted by the zenoh API and are documented [here](https://docs.rs/zenoh/0.5.0-beta.8/zenoh/net/config/index.html). * `-l, --listener ...`: A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default `tcp/0.0.0.0:7447` is used. The following locators 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, --peer ...`: A peer locator this router will try to connect to. Repeat this option to connect to several peers. * `--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.: 0A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random UUIDv4 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. * `--plugin-nolookup`: When set, zenohd will not look for plugins nor try to load any [plugin](https://zenoh.io/docs/manual/plugins/) except the ones explicitely configured with -P or --plugin. * `-P, --plugin ...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. 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:.'` . By default the zenoh router is delivered or built with 2 plugins that will be loaded at start-up. Each accepts some extra command line arguments: . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): * `--rest-http-port `: The REST plugin's http port [default: 8000] . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) . * `--no-backend`: If true, no backend (and thus no storage) are created at startup. If false (default) the Memory backend it present at startup. * `--mem-storage ...`: A memory storage to be created at start-up. Repeat this option to created several storages * `--backend-search-dir ...`: A directory where to search for backends libraries to load. Repeat this option to specify several search directories'. By default, the backends libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` . ------------------------------- ## 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 Gitter channel](https://gitter.im/atolab/zenoh), 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.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4669 Filename: ./0.5.0-beta.9/zenohd_0.5.0~beta.9_armel.deb Size: 1519472 MD5sum: 4b0f4a68928f4b0a359da5cda0dcfff2 SHA1: 26efe192ef7b706fd84d106f2acb995eff1e9184 SHA256: 95dc5434d93eb3ec6f027dfe8b4a29dc89b82e5e4324594ef4fc160e47b7e529 SHA512: 651c872fa84d820fbba3d100e65a041bd669428ae38162bdcd39424a9430991487cb86ff7847536a083a7b5e4d383cc01589248b6c4637b48e0c550d9769e167 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) [![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 (pronounce _/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 install and test it . See our _"Getting started"_ tour starting with the [zenoh key concepts](https://zenoh.io/docs/getting-started/key-concepts/). . ------------------------------- ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.5.1), so no special configuration is required from your side. To build zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . The zenoh 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/eval** - run: `./target/release/examples/z_eval` - in another shell run: `./target/release/examples/z_get` - the eval should display the log in it's listener, and the get should receive the eval result. . **Routed tests:** . - **put/store/get** - run the zenoh router with a memory storage: `./target/release/zenohd --mem-storage '/demo/example/**'` - 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 --mem-storage '/demo/example/**'` - 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 a memory storage: `./target/release/zenohd --mem-storage '/demo/example/**'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the backends of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/backend/*'` - 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/**/storage/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/properties' -d 'path_expr=/demo/mystore/**' http://localhost:8000/@/router/local/plugin/storages/backend/memory/storage/my-storage` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storage/*'` . . See other examples of zenoh usage: - with the zenoh API in [zenoh/examples/zenoh](https://github.com/eclipse-zenoh/zenoh/tree/master/zenoh/examples/zenoh) - with the zenoh-net API in [zenoh/examples/zenoh-net](https://github.com/eclipse-zenoh/zenoh/tree/master/zenoh/examples/zenoh-net) . ------------------------------- ## zenoh router command line arguments `zenohd` accepts the following arguments: . * `-c, --config `: a configuration file containing a list of properties with format `=` (1 per-line). The accepted property keys are the same than accepted by the zenoh API and are documented [here](https://docs.rs/zenoh/0.5.0-beta.8/zenoh/net/config/index.html). * `-l, --listener ...`: A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default `tcp/0.0.0.0:7447` is used. The following locators 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, --peer ...`: A peer locator this router will try to connect to. Repeat this option to connect to several peers. * `--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.: 0A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random UUIDv4 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. * `--plugin-nolookup`: When set, zenohd will not look for plugins nor try to load any [plugin](https://zenoh.io/docs/manual/plugins/) except the ones explicitely configured with -P or --plugin. * `-P, --plugin ...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. 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:.'` . By default the zenoh router is delivered or built with 2 plugins that will be loaded at start-up. Each accepts some extra command line arguments: . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): * `--rest-http-port `: The REST plugin's http port [default: 8000] . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) . * `--no-backend`: If true, no backend (and thus no storage) are created at startup. If false (default) the Memory backend it present at startup. * `--mem-storage ...`: A memory storage to be created at start-up. Repeat this option to created several storages * `--backend-search-dir ...`: A directory where to search for backends libraries to load. Repeat this option to specify several search directories'. By default, the backends libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` . ------------------------------- ## 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 Gitter channel](https://gitter.im/atolab/zenoh), 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.5.0~beta.9 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4545 Filename: ./0.5.0-beta.9/zenohd_0.5.0~beta.9_armhf.deb Size: 1524912 MD5sum: 02a3b72484ebb58fbb30405080f4744c SHA1: 5c0ecd857d7f962c3a1edbcffe5f21faa0169ae9 SHA256: a2209116d8eec80862434f96c64944a0f6ce3927b1c83335405df47463ce1ff5 SHA512: 01e87cf67ba3e56ad05b51636123aa12b47d29c3cb1b1d1d4db96f268938c3616c44ce6d223e031df11416e5ed54ce53eb3e83b249c5e4530cb3d38e3aea3956 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) [![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 (pronounce _/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 install and test it . See our _"Getting started"_ tour starting with the [zenoh key concepts](https://zenoh.io/docs/getting-started/key-concepts/). . ------------------------------- ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.5.1), so no special configuration is required from your side. To build zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . The zenoh 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/eval** - run: `./target/release/examples/z_eval` - in another shell run: `./target/release/examples/z_get` - the eval should display the log in it's listener, and the get should receive the eval result. . **Routed tests:** . - **put/store/get** - run the zenoh router with a memory storage: `./target/release/zenohd --mem-storage '/demo/example/**'` - 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 --mem-storage '/demo/example/**'` - 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 a memory storage: `./target/release/zenohd --mem-storage '/demo/example/**'` - in another shell, get info of the zenoh router via the zenoh admin space: . `curl http://localhost:8000/@/router/local` - get the backends of the router (only memory by default): `curl 'http://localhost:8000/@/router/local/**/backend/*'` - 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/**/storage/*'` - add another memory storage on `/demo/mystore/**`: `curl -X PUT -H 'content-type:application/properties' -d 'path_expr=/demo/mystore/**' http://localhost:8000/@/router/local/plugin/storages/backend/memory/storage/my-storage` - check it has been created: `curl 'http://localhost:8000/@/router/local/**/storage/*'` . . See other examples of zenoh usage: - with the zenoh API in [zenoh/examples/zenoh](https://github.com/eclipse-zenoh/zenoh/tree/master/zenoh/examples/zenoh) - with the zenoh-net API in [zenoh/examples/zenoh-net](https://github.com/eclipse-zenoh/zenoh/tree/master/zenoh/examples/zenoh-net) . ------------------------------- ## zenoh router command line arguments `zenohd` accepts the following arguments: . * `-c, --config `: a configuration file containing a list of properties with format `=` (1 per-line). The accepted property keys are the same than accepted by the zenoh API and are documented [here](https://docs.rs/zenoh/0.5.0-beta.8/zenoh/net/config/index.html). * `-l, --listener ...`: A locator on which this router will listen for incoming sessions. Repeat this option to open several listeners. By default `tcp/0.0.0.0:7447` is used. The following locators 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, --peer ...`: A peer locator this router will try to connect to. Repeat this option to connect to several peers. * `--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.: 0A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random UUIDv4 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. * `--plugin-nolookup`: When set, zenohd will not look for plugins nor try to load any [plugin](https://zenoh.io/docs/manual/plugins/) except the ones explicitely configured with -P or --plugin. * `-P, --plugin ...`: A [plugin](https://zenoh.io/docs/manual/plugins/) that must be loaded. 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:.'` . By default the zenoh router is delivered or built with 2 plugins that will be loaded at start-up. Each accepts some extra command line arguments: . **[REST plugin](https://zenoh.io/docs/manual/plugin-http/)** (exposing a REST API): * `--rest-http-port `: The REST plugin's http port [default: 8000] . **[Storages plugin](https://zenoh.io/docs/manual/plugin-storages/)** (managing [backends and storages](https://zenoh.io/docs/manual/backends/)) . * `--no-backend`: If true, no backend (and thus no storage) are created at startup. If false (default) the Memory backend it present at startup. * `--mem-storage ...`: A memory storage to be created at start-up. Repeat this option to created several storages * `--backend-search-dir ...`: A directory where to search for backends libraries to load. Repeat this option to specify several search directories'. By default, the backends libraries will be searched in: `'/usr/local/lib:/usr/lib:~/.zenoh/lib:.'` . ------------------------------- ## 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 Gitter channel](https://gitter.im/atolab/zenoh), 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.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 99 Depends: libzenohc (=0.6.0~dev) Filename: ./0.6.0-beta.1/libzenohc-dev_0.6.0~beta.1_amd64.deb Size: 21020 MD5sum: 3a6df27d9c725338c9ab63fa072badb3 SHA1: 743b2b7571162ccd7bba6f8a9997c5148c4d6f76 SHA256: 03686b548a50c6c944fb85fe8f76ba6673acfbca916f0f5ac0d798c4ce29f8ed SHA512: 2d1577c18ca6552e875d267aca2db98d1f4dc6938cb55daf08ec2854590402c3978306746835fdd5e4f04f163ad049fcecb553443bc565e1ca58e6268fbdacd0 Homepage: http://zenoh.io Description: The zenoh C client 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/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 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. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## 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 $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. 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.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 99 Depends: libzenohc (=0.6.0~dev) Filename: ./0.6.0-beta.1/libzenohc-dev_0.6.0~beta.1_arm64.deb Size: 21008 MD5sum: c573d12c530bfd08290598731823516d SHA1: 8da1aebed402aa56dd228032dfb71f5d0a6f3557 SHA256: 34ae99bafd3ecc126fb91e976951323bf1012dd3944b299756c96665e2a1c52d SHA512: f584133e660774ec333394a612ab64e9a99a1814e809d9009a03bf9a97f14a49ebd188d2be371d6a545b258227d6ed7e0e97078fff11746dddf15c7fc19df98c Homepage: http://zenoh.io Description: The zenoh C client 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/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 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. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## 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 $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. 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.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 99 Depends: libzenohc (=0.6.0~dev) Filename: ./0.6.0-beta.1/libzenohc-dev_0.6.0~beta.1_armel.deb Size: 21020 MD5sum: 814c6e2626e62b920c6781ba507dedbd SHA1: 7aab40967ec7123b12382f29accb3e3076f5e9bd SHA256: aae39816e6da56fd699c98588810dfbfb1b3de30d37fee1e4cf3e79df6cc6c72 SHA512: 1d29434931a4cf95c985a91b66a3017d6c38301273c87d5940d26e476eb6f401a76700c1bf376a11a0b11277690ceace079481b723546ddf8a07b670b73fe497 Homepage: http://zenoh.io Description: The zenoh C client 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/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 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. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## 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 $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. 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.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 99 Depends: libzenohc (=0.6.0~dev) Filename: ./0.6.0-beta.1/libzenohc-dev_0.6.0~beta.1_armhf.deb Size: 21012 MD5sum: d34df53f888bfef6859fcdbe7631ad12 SHA1: 8b0681f03e9a40179a179ed04fde9005fb04f018 SHA256: 71d0e5fec061c5cfadef239e1f6087f37f2fdb1bb4b3550c28a44f7aed1928c5 SHA512: 5d0d9789cc006eeb678951f0cfceaa7d75374c13497dd33ffe98829df81a8aabafb45acaac55edb5b817c7fe12e56f532c4d38b0fe56683ea640909c4a8c148b Homepage: http://zenoh.io Description: The zenoh C client 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/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 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. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## 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 $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10726 Depends: libc6 (>= 2.28) Filename: ./0.6.0-beta.1/libzenohc_0.6.0~beta.1_amd64.deb Size: 2870524 MD5sum: 8c40c820718cddac6fb0a3ff6a881fa0 SHA1: 343c836ff68559cb464a116a10a9197553331fb1 SHA256: 5a0ecb6f7e383da7fcd1c68bc1c1e8ec001a9a6fb6b3c80ab740e4ebb18c40a1 SHA512: f4ab30733cc919a1f62f3a9bce91b326cea9b492c4a7713cd7357134f686115bce0b7e0b7cdf2e183c6af49f5c19074b9604a3f8d75803f320531cdda2173ab7 Homepage: http://zenoh.io Description: The zenoh C client 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/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 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. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## 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 $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9584 Depends: libc6:arm64 (>= 2.31) Filename: ./0.6.0-beta.1/libzenohc_0.6.0~beta.1_arm64.deb Size: 2570328 MD5sum: 4b57ad079f9b86ea416fd7674a6c8ca5 SHA1: e1499771b7b058ecef1d68731d47fba12718cb15 SHA256: 3135bd05ce7520476d18a4096c3665792d8ff3309ddd82f781d2a6e13d13b63e SHA512: 54f7e775c684140d14537f9ffa5233ddcd0b1ba8cf0768f19b349c17b11b87031750a434b5a99b57ab76d2e96b06ee19bc45803d2c36314c9d2772949dc55fd2 Homepage: http://zenoh.io Description: The zenoh C client 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/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 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. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## 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 $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9938 Depends: libc6:armel (>= 2.31) Filename: ./0.6.0-beta.1/libzenohc_0.6.0~beta.1_armel.deb Size: 2625640 MD5sum: ec8014dee0986c144663676ad6ec4dc3 SHA1: 7e94629561638fd5f9da7dd35466d443c77efb7d SHA256: f64a5af2a143f9157f2cef85d23aafadf95f0cb13fb565b56e92d57e1d4a89b9 SHA512: 8395636d8cc2210a6e6bd76e9632e160611198c1a5aef8cda5dd1d5d260554a34c3e33dd9a8f8c003c2b7eed69f392fd377dff8331e17c89e74d1b38ae284e25 Homepage: http://zenoh.io Description: The zenoh C client 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/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 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. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## 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 $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9798 Depends: libc6:armhf (>= 2.31) Filename: ./0.6.0-beta.1/libzenohc_0.6.0~beta.1_armhf.deb Size: 2630252 MD5sum: cb3870284ecd5900ed558039ba3dee1a SHA1: a6ac6f97864dd5b1ef60e6985b3f5c69426d2b4f SHA256: ef8fa33419f04679b43a28b5a518fd07afc25377974d8496cf998046c3c8fab7 SHA512: 1d01c93850e25c0cf9db0fc3a36f532229ad70bd7906594fd6ae909c3875ac316c578030a4cd7df50645f6cc8b9250f301267eb51a73c1f92dc57b34da75db3e Homepage: http://zenoh.io Description: The zenoh C client 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/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 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. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## 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 $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohpico-dev Architecture: amd64 Version: 0.6.20220929dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 344 Depends: libzenohpico (=0.6.20220929dev) Filename: ./0.6.0-beta.1/libzenohpico-dev_0.6.20220929dev_amd64.deb Size: 47028 MD5sum: 413ee9a2fb14341de06fb502fd800aea SHA1: 4712b4f146f037c2d0846986bd3dd5b40e5a480d SHA256: 672b22158f1552da12e262b616cd269d1ee08f1f6d8d46947c823f3f73d5273d SHA512: 328003d76e83924747c7dfd92172ffeae99a2df1225905927684bc3ad4bce1fbe901e4f66575c2aae2979763c07cd5b4e0d2e147351c53bbe3a9bf2437c9a78a Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: arm Version: 0.6.20220929dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 344 Depends: libzenohpico (=0.6.20220929dev) Filename: ./0.6.0-beta.1/libzenohpico-dev_0.6.20220929dev_arm.deb Size: 47018 MD5sum: 092129851ece9d9791a31034f5707977 SHA1: ff56a4cfbc6561ebb2f5a470e79d3482e246eb81 SHA256: 34a75549df72b3e79036dda64e0976a27a2b8ff1401c482aab5acccfb352e308 SHA512: 5bf22434250b2584fe78b36ed49f538ce184faabd795d4889ac98645fddf85ccf725d86e7c2c23fcb1aaae11cba025917eaa1c44a3a7a0ac2f2c56eaeb83f162 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: arm64 Version: 0.6.20220929dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 344 Depends: libzenohpico (=0.6.20220929dev) Filename: ./0.6.0-beta.1/libzenohpico-dev_0.6.20220929dev_arm64.deb Size: 47028 MD5sum: bba7cb0680d6f56f5e6784d4f098b267 SHA1: d13e784bf50aa8164d5477a175da8d66af91684d SHA256: 3be0175ef6001523eafa6fbe6fb3acd0e76fda3ac28012162ae7303c2385cd2e SHA512: 3450ba084e5c148b220808acfb53fa68b3650e328cc1c201a8364ff8eba43b692df1a05c240f3461acb21b90232f8d45fe7b291e7d136542f1eab640f2a2b85c Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: armhf Version: 0.6.20220929dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 344 Depends: libzenohpico (=0.6.20220929dev) Filename: ./0.6.0-beta.1/libzenohpico-dev_0.6.20220929dev_armhf.deb Size: 47028 MD5sum: 7022f5180373eed4e8c868c9b9ad4505 SHA1: adff60ca173e3fc06700d7849f706e264af934de SHA256: 83fe19c64fbab7801e0cd1381feb3bbb71f154ed468bbb3096a10b9997caa800 SHA512: c8d4e7bf7ca36a61bc51b076f03fd4b27f5a108b9da07835c184a9a6f2816e4f1c403136e5f600890701892c4b5132e4a9777bf388c30fcc85a773a2b5bd7c7d Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: i386 Version: 0.6.20220929dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 344 Depends: libzenohpico (=0.6.20220929dev) Filename: ./0.6.0-beta.1/libzenohpico-dev_0.6.20220929dev_i386.deb Size: 47018 MD5sum: da4f47ce7be35f4f5d062a63bc6bb6fe SHA1: 35c024a97696860a297b5355acfdf6d463f7e5f8 SHA256: 99695b5ad60bf44211788fdeb1804cc26d2f53bb082499b8f2dffd47604365e1 SHA512: 490a203c1fc6cf4d73156d19b2ab535a584bd08ff20a5e3532beac12ab8855f328781a25a8541c2286440eaf85237fe1b59607b2d716b707d91df1715545d47d Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: mips Version: 0.6.20220929dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 344 Depends: libzenohpico (=0.6.20220929dev) Filename: ./0.6.0-beta.1/libzenohpico-dev_0.6.20220929dev_mips.deb Size: 47028 MD5sum: 9c9f910bea25d83ad521e36c7ab548d7 SHA1: c8d076d92e54d107babd7e5ebb92fa2fe2c609c6 SHA256: 60488a17db956e257af62849dc19c630b5bfb7c10ed533c79ec6d05c775d1465 SHA512: 715e5987368675b7dd1bf90d03dd8eec77afa93047183edca2973a88c5aab82aad8a8e4eb09ed61ae1536af047df72278408d52d1726bce269dad30e0a37abb1 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico Architecture: amd64 Version: 0.6.20220929dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.6.0-beta.1/libzenohpico_0.6.20220929dev_amd64.deb Size: 608 MD5sum: 25213de3333eef1e1169177dfc5a1409 SHA1: 8c8b03dbf6630493004ccaca3a71cafe46c5ba42 SHA256: 08be143ec5e9c387df3f600f0d2b3076610c75991ae9018da96670caa6f25069 SHA512: 8d977d8d7917b6eb3c6010c3225af568ab8d4a4cf547b1d6094ad322003ffde8afc90b8addd3caf1d13be9e5ab00f04360e4b6cc3c8fa66546b6b052688f191e Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: arm Version: 0.6.20220929dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.6.0-beta.1/libzenohpico_0.6.20220929dev_arm.deb Size: 606 MD5sum: e72f4f7aff6314a426503bd02863cdf8 SHA1: 5ba8578f9afe6d82533de91ec2b5f6534f509d36 SHA256: 61fce3e36db1c315830f9fdce88b569118212ed787639722b728498ebdf6d70d SHA512: 923bb58b9377b00733016be68fa4d27aca2824d7deaac87ada9c43d16981000de60e481245f3e66caf5efad35ed091f5f8c7bdc2365b6e21cc5082f279a101ba Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: arm64 Version: 0.6.20220929dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.6.0-beta.1/libzenohpico_0.6.20220929dev_arm64.deb Size: 610 MD5sum: 1ffb05a7d44ec3463150f91db327ca6d SHA1: 8376466ea8a1068eb87c8edfbeb78174eabf8e5f SHA256: 498fc81b2c01bb9214eafc55a53bdbc29fe2e9b295ebe2c10969b685b42ff997 SHA512: 15fdd83322d1c270d4115279e04bb39e7a3897ff380ff71a5cb266e6901f84a19434bc4faac9ec13deadf3dd4584ff9bdff863e619b22b16c88db980c7c98972 Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: armhf Version: 0.6.20220929dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.6.0-beta.1/libzenohpico_0.6.20220929dev_armhf.deb Size: 610 MD5sum: 74176c7ccdb2ed267039658292550e58 SHA1: 8051b39a07ca40f49c312f7ea35ee7a2b6c0f85f SHA256: 7513e0e44503408c8531fa688e457a08422cf0aba87b07a37909af7ac39a3d70 SHA512: cc2c9f178dde6767e74bb61e4fe521bce286ee0c6bc1e6db1c42fb976da791a239a565dd48bb12c1f59b1db9a6d56330ce69ef6040fb9cb5ad4ea1993c9d59aa Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: i386 Version: 0.6.20220929dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.6.0-beta.1/libzenohpico_0.6.20220929dev_i386.deb Size: 608 MD5sum: 1222e7998d741bc4d11c67c50ea8241c SHA1: daf50c649a8502984f277644ea546cfe5b5f7de4 SHA256: 1aef814c51b28ddae550d0f58cb696d9d074ccf3c95d59a161d07783c202b001 SHA512: 17dee58924eca25099ff1e762753d258c2f3501669e33cd6c13115af6c334a780663c84aa493c8eeaa08c4d81ca9bf5ff977dae014afdba82f518a6a4874d7d3 Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: mips Version: 0.6.20220929dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.6.0-beta.1/libzenohpico_0.6.20220929dev_mips.deb Size: 608 MD5sum: 53a8d260d548a37e96738deb803ac2e1 SHA1: 1a51faf19721cad94a1277f2c44a97c66418cb26 SHA256: 4a87fbf2e01a2fbe5694e4fec6e73b00192691d46f6b40bff4f73fc6a54ea1fc SHA512: 69b775e31571eccc5095e3d95d7148aec916f80db0f8c3deb72d92bf4ada382e7b854db8e398a85e80c885c96fc94e3780e227060e111cc1ab5ec85123e916d2 Description: The C client library for Eclipse zenoh targeting pico devices Package: zenoh-backend-filesystem Architecture: amd64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9058 Depends: zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-backend-filesystem_0.6.0~beta.1_amd64.deb Size: 2735212 MD5sum: 25448190d975002b93bc98d0c8f12dc2 SHA1: feb4a010ac5c13e40eeaf951244582c6c5b44140 SHA256: 054a1e34d8d71b356576513dafb0b07dd9019f6b299b01fb6b287694a8b2f5ed SHA512: a4985e0a007fc89ad65364766b7affa969251fb380ece27c067c2fffb8d2938168aa118d843fb619302b0bf73343e4789fe70160fc6a8d686b8c9f7e65adb2f1 Description: [generated from Rust crate zenoh_backend_filesystem] Package: zenoh-backend-filesystem Architecture: arm64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7739 Depends: zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-backend-filesystem_0.6.0~beta.1_arm64.deb Size: 2260956 MD5sum: a8bb144ae490386bff981d87a0797a97 SHA1: a0269a96fc0d1f52db5bf17857608ab79856ef8b SHA256: bdd26b59cadc9bf095339801a2a5c3e59b1c16a0062817cb235a7c99af1643ed SHA512: fdf5e5bfa82e658091a9b9194fdc217e682763f786e49881a2cec7bf62f0efdd3300dd8da8452381ad24d9bb9ca3e24bec1d3fd224b9d667e771b2196dc3d317 Description: [generated from Rust crate zenoh_backend_filesystem] Package: zenoh-backend-filesystem Architecture: armel Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7313 Depends: zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-backend-filesystem_0.6.0~beta.1_armel.deb Size: 2231512 MD5sum: b9db55406e1b36a6dcfd7e5c240250fb SHA1: 54aca06fc06e8b03fe13f09fe07ccb0c57b8ff74 SHA256: 5b4f90f88c3fe4c3adf97fa2bc30e6f9d089102012be6b955f827a9d43bf49b0 SHA512: 9cc4ac4694a06b4134087787bf91fdc228237cbfd4f2eceb839de1b197eedb29f02346dda92ff0e8cfae0c56bbf3a70d45be578dfe5c080cdeffe2b7bd4db656 Description: [generated from Rust crate zenoh_backend_filesystem] Package: zenoh-backend-filesystem Architecture: armhf Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5769 Depends: zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-backend-filesystem_0.6.0~beta.1_armhf.deb Size: 2301044 MD5sum: 38a6609b97d581dff9251411ce80b36e SHA1: f41fe73286458ffe93dc97927190c40ba8219e09 SHA256: 811a4becbbc6a91a824abb1a3184b1dc4b0d120965b6710e5c74c497dfe6e750 SHA512: e1e7b9f8073a073326ac11156fdd4d46dad4ead714bd8dc7ce1f327e88636f7762029cf55833f30cbeef1348fa7ccd15815bf43723ba5a5773e064cfd307c2bc Description: [generated from Rust crate zenoh_backend_filesystem] Package: zenoh-backend-influxdb Architecture: amd64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4921 Depends: zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-backend-influxdb_0.6.0~beta.1_amd64.deb Size: 1512484 MD5sum: 1351cafb3426fbd8a2ae72dd770285fc SHA1: 3f6700a018089b08366663c3e65a6bae7375f5c7 SHA256: 8917624686fd090226f76919c51baa95a0ff5185c7b14b7cc1a493d059681df4 SHA512: 7342af57e486ae91725d630a2cdb735b6fb6aabf14b4685c159d5e470fef9af0078ef8ee70d49d552f22c2da7d7f4ea36afce3002da08d8af15eb7861e59ca3b Description: [generated from Rust crate zenoh_backend_influxdb] Package: zenoh-backend-influxdb Architecture: arm64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4353 Depends: zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-backend-influxdb_0.6.0~beta.1_arm64.deb Size: 1320300 MD5sum: db218403921d36648aa8692d1e6b558c SHA1: 7087ce8a1b27caa5d52cf3b66bf202329420d9b2 SHA256: b368bf0efaf7f12bdc01c5d06644e9e53b362496ce154b130a0892d1631657b5 SHA512: 5a1b4d2798f46fd5d01f52346f1f4eb74644fee163275d267e0373c1010034dda62f694feaa9533d14b7be37dc67916e762b8cea4dcdc58d1db74186eadc8f1d Description: [generated from Rust crate zenoh_backend_influxdb] Package: zenoh-backend-influxdb Architecture: armel Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3976 Depends: zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-backend-influxdb_0.6.0~beta.1_armel.deb Size: 1153228 MD5sum: 106d8b767bc4f28087867b5898e632d4 SHA1: 82dc129c6f45f9a917fcbdf3c87634b7be6b361e SHA256: 503370682524b352a968147e01918bc06e80dbd624c12581ea30656c9801817f SHA512: 5790b21d181979a5e8a91347ea66ac9b6c806328d54a8b92df528ed84d5ad172af574bd0fc7e3ede1f7c2ebd6c1015a343dd27cdba25fee3bb2f0a855abce295 Description: [generated from Rust crate zenoh_backend_influxdb] Package: zenoh-backend-influxdb Architecture: armhf Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3884 Depends: zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-backend-influxdb_0.6.0~beta.1_armhf.deb Size: 1154164 MD5sum: 3e62894e18c222ec902aa95a6d390833 SHA1: f8f707cbfbe6972e1e9d0db1d4c66a4196931331 SHA256: fd74183b30113bfb61f5eab2f2ffc58ebbbfd15591e13be532d9658ca0f82f4d SHA512: 8f1e6fe6b59814f63a4584fdd469d58b2df73a9e22cc43536bf47e3c5e59a3d0096771eea3bc7e79191e8fe7efaea0306b0db0aba607cbb9102b337ed55a2bae Description: [generated from Rust crate zenoh_backend_influxdb] Package: zenoh-backend-rocksdb Architecture: amd64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8934 Depends: zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-backend-rocksdb_0.6.0~beta.1_amd64.deb Size: 2707936 MD5sum: 1644f2fb9f2c28a657e012d82e6e3774 SHA1: 11915a54b5c06f2d0e8887eeaa689436faec5a8a SHA256: 54082c8b3a313e1d4b2223f934138909f669c22385f138c9d1691907875f23e4 SHA512: a5b41ad226c7d9705c185f03bbf1b6d799eab03ef16c59285d5b8063ba17ddd6afaf42c05fb02a2f421397c32e062e8590d2dfc14223e0469d6b95518f9f2743 Description: [generated from Rust crate zenoh_backend_rocksdb] Package: zenoh-backend-rocksdb Architecture: arm64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7595 Depends: zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-backend-rocksdb_0.6.0~beta.1_arm64.deb Size: 2239168 MD5sum: 8aa09fe69cec01a6f72f652f62b722bf SHA1: cc48742050e962249f9c155b2e487cb8a69b9e88 SHA256: 954c1f148d611785de953d52737e6459e868593c188c771a4368afc40d649a52 SHA512: 9a61f4183d62cd4227c9b544464797bd85cb053525a446b0410cc769fae7393f9e29ad05d3196dde6cb692a37c639c81c2229a0c0194b72ae80c507af329a99e Description: [generated from Rust crate zenoh_backend_rocksdb] Package: zenoh-backend-rocksdb Architecture: armel Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7253 Depends: zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-backend-rocksdb_0.6.0~beta.1_armel.deb Size: 2211356 MD5sum: 593e0ab2fa00663c07a750dc92c0b54c SHA1: 015d4e6dacb5fbaf7748ac1419d1081320bb1795 SHA256: 7c0dbb2bf6f2f8c081b631e8905b48dc6e773d401310497a4a76cc85b321b983 SHA512: d2d101910f037e618153de48d1aa4d3bda81fdfa5487c90041980e08384ae275ad84dcd0b29f5e94f006d535ccc93d7933094eed8ca93581e9eacba15ec9cbde Description: [generated from Rust crate zenoh_backend_rocksdb] Package: zenoh-backend-rocksdb Architecture: armhf Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5677 Depends: zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-backend-rocksdb_0.6.0~beta.1_armhf.deb Size: 2278804 MD5sum: f26f77ccb71edc350cb93af640bcb31f SHA1: 013c775a860dba9f6824e987ef7f79c61a6f91bd SHA256: 0dffe496e316ba23507013f74331d221b85f920ba037e10fd5020be3b8c6f565 SHA512: 92eec5ec4839cd31ecde36481f019e4c407e5187ff02af74421ddfb6c19c74fa9c0ca9b1a466bfc4388fe32239fe2f4b4973747210f2b8611bfcc01649954465 Description: [generated from Rust crate zenoh_backend_rocksdb] Package: zenoh-bridge-dds Architecture: amd64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9364 Depends: libc6 (>= 2.29) Filename: ./0.6.0-beta.1/zenoh-bridge-dds_0.6.0~beta.1_amd64.deb Size: 2945608 MD5sum: 6cd39628c998961524c8645c5be7bc0b SHA1: cfedccd53855bddc086dbeb284f3cdc338d27960 SHA256: 3b2673fd39d54534ccb5d69aa786f2fa0982c4080a30b4f3f1d28df5bd6269bb SHA512: 4f376e44517231f73b65fa7995132c0d3d799d0ba71380861f88e0ca1141c988545ba46bdac91f9edd6b1fa86d3d6851a1d6b377e638e148c33ee06019a643b6 Homepage: http://zenoh.io Description: Zenoh plugin 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.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8080 Filename: ./0.6.0-beta.1/zenoh-bridge-dds_0.6.0~beta.1_arm64.deb Size: 2620912 MD5sum: 417f16fac83de2f4b8f9679f7733f8b2 SHA1: 193c45119a7830e941e5ed308007954cfb9ac2fc SHA256: 3fd963be98ed148122617b0547e4ed69bcbc9aac81bf0b0688caf12344348938 SHA512: 3baab38cb9672ec0d49c19f89562163ed0945199443d4e0abbe7260520f74302b6f9d8df1035bf8ed22c248ce3fe19691e962db389b288de7545967198aab692 Homepage: http://zenoh.io Description: Zenoh plugin 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.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8442 Filename: ./0.6.0-beta.1/zenoh-bridge-dds_0.6.0~beta.1_armel.deb Size: 2609164 MD5sum: 72c56acd0881a63475642c10473a0929 SHA1: b684dafe4b8258f0f9c53368bd9457a81314bd08 SHA256: ae7a3fbf578b285a10603e1a099b9e03bb23dbca5d05a0976e0a24469985aecd SHA512: 07fb364163595c7617458dfc8fd078d78091136678cbd9eb7b257e1a8b788fd201c49ac59b84015a1de5c1ecdf75e292d9e9fd21e2d99b784324374606d4b9d5 Homepage: http://zenoh.io Description: Zenoh plugin 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.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8058 Filename: ./0.6.0-beta.1/zenoh-bridge-dds_0.6.0~beta.1_armhf.deb Size: 2629856 MD5sum: 4af35f65bfa08e45775765ab6596066d SHA1: 7d9f6ce721f35b60b3f327e0b070a023f3e0bd74 SHA256: 3b1b9c72efa97c105798f1d960cd9ae935c3c1324790c6ac6620c4aebcbb2cd5 SHA512: 8ccb7707e82f90f2392bafa2146dc087ce264507e6e128e84f8577e352354b41a0b520d8cde24e9c6af111201c29167f6182abe58f19bd0ba1fbfbe35597b731 Homepage: http://zenoh.io Description: Zenoh plugin 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-plugin-dds Architecture: amd64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3902 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-dds_0.6.0~beta.1_amd64.deb Size: 1147916 MD5sum: 7eb86db8702a3c4dc5efe2932e70d55f SHA1: 6b9e799607bfebb3340ac68979bcde847bd7af01 SHA256: 5a00ca0a432a5317b88c034962917fc5cfcc3a84bce3ed17496b1c183d5c6ee4 SHA512: 055f483a4f7a56a447184b8b82b52aa6db877cc72596e139c400b1d45481c46c261fb415feb4f697ce5899e8d6aacd11f7edf68a306e2416f96609066e67ca2f Homepage: http://zenoh.io Description: Zenoh plugin 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-plugin-dds Architecture: arm64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3442 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-dds_0.6.0~beta.1_arm64.deb Size: 987312 MD5sum: 24bee50067e718df3c8b3642e6f8c91e SHA1: 611147db2b67387a4a06dc3364c6da459651984e SHA256: 31d15cf7b7e129ffda32a742de49c7ab8e412e9899ddc8ff5d46026797b5fcd8 SHA512: 7ba657b6bddb15054961b3c610271dcf6a38dc8df625249e654e4e67f2fae6cb18f1e5870f28edd33adaebdce85a2b8260fb4d4f5a5e0e7c1e4d075d0ea38138 Homepage: http://zenoh.io Description: Zenoh plugin 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-plugin-dds Architecture: armel Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3465 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-dds_0.6.0~beta.1_armel.deb Size: 1017568 MD5sum: 583d886589ea3808218dd74fd752636d SHA1: cc322fea56b7be3aa82fd47e8523c8f3596fc281 SHA256: b617853714cee389cc50a55291451bede3bfe7b31829207cb3d1d6ba8a056e11 SHA512: a02a7cc29849bf55aebfa20d13f57eb1f78ccee6dd21e8118ead79a15d53393453bec3f0dd19f376689844f76526fe812a7b30a63795ce67ec18009fb56300dd Homepage: http://zenoh.io Description: Zenoh plugin 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-plugin-dds Architecture: armhf Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3213 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-dds_0.6.0~beta.1_armhf.deb Size: 1028208 MD5sum: 52cf327b432baf37ae5f1452cd72c618 SHA1: cfdbf4700ef67ddeae2f66724ea6d7596aacb750 SHA256: 6b538df72ab7dd7f75e5ca6109bf0a000a8d904f98dac2f8d92e88a682fbec06 SHA512: 06e5be612c3d131033e7185dd5524b3b5de5e64f94b5f66f855e2dbfb246ae0ccb48bd90b1e674d20d449427438273beaf908e1abb6684ee2d1e21db1c10e9ad Homepage: http://zenoh.io Description: Zenoh plugin 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-plugin-rest Architecture: amd64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3274 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-rest_0.6.0~beta.1_amd64.deb Size: 924176 MD5sum: ae21200e814a3b24f57e47d8f073cff6 SHA1: 2cdf5061098c9b636d91768373c90250f327435c SHA256: 73bf0f984ffb23978c784017378a663465e2ac4503c9d35dab1ffb890f0f4ee2 SHA512: 7b4848c8067a8e4612c8c241fda07110b4a8035ef807846dd95a0f0313a8422cd0c3a686d01606c343a582bf2a2825006ee3ec4581ad414065c556b3dd3751e6 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-plugin-rest Architecture: arm64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2910 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-rest_0.6.0~beta.1_arm64.deb Size: 804908 MD5sum: 5c9f2de75135855be3a4af74ad19e24d SHA1: e809ca0b6591bb19ccffcc4f606863020f70413f SHA256: 4202a3a7fa635d373dd892f3b44c570d6ee743512582dba4823da5041b0e2e99 SHA512: 321e97f31e63320f3d08a6038bbf9a614c40c68288cc5389566541ef69cdeefdddaa40aa929669abe245c3f8d60940b508e3187607e2c34880aa099732ccbd6b 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-plugin-rest Architecture: armel Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2881 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-rest_0.6.0~beta.1_armel.deb Size: 821144 MD5sum: 1241287a6bde35e7d2dad8e5fae6ad13 SHA1: 06e7ca057231b2e3176d4942e68a3e8d9493cc07 SHA256: 8464b7c326d7425ffb1376745645a85267acc24f5ca142414288c63287066799 SHA512: ca6118d4ffb73de01c351b1999a01be14096b423dfafb3e660ac0bb0ce4b84418348bca7b87b33091c10fba5deb4b2bced7aaee27ff255a2e555426c00d9e1b4 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-plugin-rest Architecture: armhf Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2821 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-rest_0.6.0~beta.1_armhf.deb Size: 814708 MD5sum: 2864deeb24cbc08798acea55310f7189 SHA1: fc42303690cd3b01bf1d7385ad2a8a1cf96175de SHA256: 224d34de5a651a51272461357838b7db8813f26abb5f32e8434456360aaffcec SHA512: 938906e248c0280b95d0366f8e8cdaba6bbe948897fb9b17a7c166c82bf1775a32cf78b173a9729f4d040455a38a642d9f706b691a76d1b7d5d4ef5ab582d1ae 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-plugin-storage-manager Architecture: amd64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2982 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-storage-manager_0.6.0~beta.1_amd64.deb Size: 887000 MD5sum: a4d4b54fc4bc8027496772e1a3989502 SHA1: ce4025c721273d261c23fe26ef295ba0f0571916 SHA256: b7eb85e4707c48deec02504690d07f46fac4e024e40f47e33e0bda53ee19be94 SHA512: 065050e65ed69044c3a1fac9d97237c56c8fb7e6aede736e4bb58994466d6e2f97739ef498cd7cf2ecfa03ad3b41b37c51bc6e907d075450bf48823abe0ba103 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-plugin-storage-manager Architecture: arm64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2626 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-storage-manager_0.6.0~beta.1_arm64.deb Size: 771440 MD5sum: c12c5694004fa55dd0fa0deb8308ec54 SHA1: 97d6c61febafe9a4c2a3092caf1c1dc02f39bd4a SHA256: d5374c5177ce48758c96446e44e8c64e24a344b01d828e5a35f4afd1cecb09b0 SHA512: 074664e99b2b0a5d6fa7f04a20826c6ab82410fbb66323a8c48d87f3cf19a59a56eccaaf318da200a188ce7409a4004c1689c04d28b3eeae84163243ab3c067a 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-plugin-storage-manager Architecture: armel Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2677 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-storage-manager_0.6.0~beta.1_armel.deb Size: 818992 MD5sum: d3beae0647c55ff212a87fa02245a9b9 SHA1: 884e9b0827963fd5950ee8589d4a191bb98b0e6e SHA256: 14cdc33e2e49db681da5cd1feed1eaccf1bac05726b26a150a31941fa43742b1 SHA512: 922569b15747c4393c0834ae5cfa0b104f9cf0af433b1cac50a7026886b69ba9468ee240e09bc20b6d525010213a642ba3018e4a2942cfba1ebf0bfa7425ee3d 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-plugin-storage-manager Architecture: armhf Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2621 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-storage-manager_0.6.0~beta.1_armhf.deb Size: 815012 MD5sum: 664945ac81cda99dbffbfedbd18adf88 SHA1: cc53281aef407efc36f641857dd675cee3811013 SHA256: 4f2cf38f891f713170c9a3c90362a1890639fe36a1e76b29a46d285c1f73ee3f SHA512: 3b4a22bcf06baff6da95a18b7ed9f950b9761940f1074b590e47f6ae93a7a2be7c09fb4abf38da57ccafe23017c491113e6c503a06a6b4214f948c866578dcb9 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-plugin-webserver Architecture: amd64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4497 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-webserver_0.6.0~beta.1_amd64.deb Size: 1175408 MD5sum: 81be67260f195b1999c946574fc5d391 SHA1: f151908e3480da66182f925441fb97a177ee1935 SHA256: 0452cf06c1d8df53dbec0137a75659936e3e5deaf4ca5faf6cfe0d20b157cee2 SHA512: 092a1672741e1634758a8ecc002acebc360e00c35460f97fa819a3c1201ff4124b855c9d6d763e5f286dee521c98eb88862a4447a6aa84acc5c5ce97519f0700 Description: [generated from Rust crate zenoh_plugin_webserver] Package: zenoh-plugin-webserver Architecture: arm64 Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4145 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-webserver_0.6.0~beta.1_arm64.deb Size: 1032684 MD5sum: 0ec670579caa6d01958ebc1e9727a501 SHA1: 2ee6abbdd23dbc8906869ec26152d21ce9b358d3 SHA256: 387806bf244a1eea90d162f6501d51aeb1675969dfcf1aca18d062a04d4cb418 SHA512: 5d69cddbf6a0e6862a80ad6556ba98c01cf078285102d5a69b7db241467b6f2855630f3cadf804c977b099631378ae999b76bfcc2c6e3b459ffeafebde09a9c6 Description: [generated from Rust crate zenoh_plugin_webserver] Package: zenoh-plugin-webserver Architecture: armel Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3904 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-webserver_0.6.0~beta.1_armel.deb Size: 986596 MD5sum: af2a7d86af3b2d7217ef7478dbc7a1b8 SHA1: a10f839f55f12b86c4c8031d671f876910a271e4 SHA256: ee751bdc9b0a6288a0cc13a94293125951dee2ec109d24b733fd9e2765e965d9 SHA512: a4e36dc1dabf8bf594599fa0d947e5d5645718fe13d5d3397cf80e86989c4f9853d39d55f76eaf865cbc82853253d0f1a3b45ba8e54f6e08dbfb0b765e66e960 Description: [generated from Rust crate zenoh_plugin_webserver] Package: zenoh-plugin-webserver Architecture: armhf Version: 0.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3808 Depends: zenohd (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh-plugin-webserver_0.6.0~beta.1_armhf.deb Size: 978292 MD5sum: 46a80d3b881a137d45965ff40b797879 SHA1: 356b8036ad6d9ee1fa2cae338ffdeecb15545f42 SHA256: fed5b6494249331a1f77832248aac922a0bdde51c1e82ea6b0cc89e1e9ab8868 SHA512: 44530535e05e69ac244cd2aab93ee2df29837c55e60407094c42ff3daa28ecbcd75f381916d7045805bc135ca6a9e343d8c6ba7ced22001867cbca50278098bc Description: [generated from Rust crate zenoh_plugin_webserver] Package: zenoh Architecture: amd64 Version: 0.6.0~beta.1 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.6.0~beta.1), zenoh-plugin-rest (=0.6.0~beta.1), zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh_0.6.0~beta.1_amd64.deb Size: 836 MD5sum: a1de2e9b80224819786ac0e5ceb64021 SHA1: 363e1d12ce35bff7c8e53fb875c8ac4110d288ef SHA256: 2c8ace646c8755643d941410cd5cbc82fcb7b78d4fc751e4fa0aac7dcd4a60d7 SHA512: d12559aad2503f1c7adeaea61f25086f519658258c7b4bc85f38ed25d357c41bc095fecb24636237c439b2c67b0d41f8fbc01e59932a9a6986e625eca002a88a 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.6.0~beta.1 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.6.0~beta.1), zenoh-plugin-rest (=0.6.0~beta.1), zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh_0.6.0~beta.1_arm64.deb Size: 836 MD5sum: 5fdf03c0eb357acc330ac51f7e56e656 SHA1: 01a5ddbe7ebc73f3abe2087f17a419e792b18201 SHA256: 04154c6de345e5df219a6bafe7df155b1caaff6718d565fe4acb6e87f773106a SHA512: d3215dacf8eec633b30dc46208f3765ac70c09191f8f4346b0fb56475e7bb48c8205bb78b99d3843104796407209fda40ac1dec4580f7c9c1340bf6cb591b58b 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.6.0~beta.1 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.6.0~beta.1), zenoh-plugin-rest (=0.6.0~beta.1), zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh_0.6.0~beta.1_armel.deb Size: 832 MD5sum: dae34bccc287d47b94eacd53051c08c4 SHA1: 4862692a34b61c024e3dc63f81b07965bf0d6a95 SHA256: 8135af4d6e46a6c4f7ca4a21b134c5863d632716c5194cfc569e6520b1f67dee SHA512: a4c6544c8e4e197542b92c8e25b5e5e9e00da27c5c4edaa8a461cec1e5ff53aaf1e0dbb8ae5aba5ccf1824ea29e58f29df431b4b06361def83b8001825b6302b 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.6.0~beta.1 Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.6.0~beta.1), zenoh-plugin-rest (=0.6.0~beta.1), zenoh-plugin-storage-manager (=0.6.0~beta.1) Filename: ./0.6.0-beta.1/zenoh_0.6.0~beta.1_armhf.deb Size: 832 MD5sum: 2b3fa85a9fb1288941fe0fab786ed201 SHA1: f38e101225efdb2626f46d96ad6a7975e7272689 SHA256: 00c433bccf4b5e024a21c82d97ed4228dfad1041330f1cada8faaa86878413a2 SHA512: a92cbe0ae5f3ecb48df3065909e445c49afcc1f83874c859d36918edcac495f60726d3a26aa172dc2e5bea3d4d5e44ede90156e6a20681315b8fa900d983406e 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.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7310 Depends: libc6 (>= 2.28) Filename: ./0.6.0-beta.1/zenohd_0.6.0~beta.1_amd64.deb Size: 2262512 MD5sum: 1bf7fd54a3413dac35e735d18c1c0da7 SHA1: e22a33c450b59ccc6e8de02147716eb0b7ccdf43 SHA256: de59cbf776704ed07d6e41217fb387aec46125406a7d905c056ba09d854f461b SHA512: 4f0ba0ae0588a6a24e0f3ad2871572c1bf61393841411a212a0fc7105b907e8cb76091a48ddbf149250ca979bc22ae2065d5fbedff5eeb51bb961fd11a7179e9 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/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. . Eclipse zenoh (pronounce _/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) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## How to install and test it . See our _"Getting started"_ tour starting with the [zenoh key concepts](https://zenoh.io/docs/getting-started/key-concepts/). . ------------------------------- ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.5.1), so no special configuration is required from your side. To build zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . The zenoh 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. . ------------------------------- ## Previous 0.5 API: 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. . ------------------------------- ## 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/*'` . . 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/0.0.0.0: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.: 0A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random UUIDv4 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 `libzplugin_.so` on Unix, `libzplugin_.dylib` on MacOS or `zplugin_.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 (`0.0.0.0`) and port `8000`. . ------------------------------- ## Plugins 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-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.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6222 Depends: libc6:arm64 (>= 2.31) Filename: ./0.6.0-beta.1/zenohd_0.6.0~beta.1_arm64.deb Size: 2007804 MD5sum: 283dbc97623c337b534dfd81c3565434 SHA1: 9a1bc554cd5dc077ba303cb58cd26547d8fbf35d SHA256: 64cc8a67b49e72e6751b220b3ce6c832108a3a1b56d9c7842e599b38899d109b SHA512: 62c0583df1fecd5a0e85183dacb17e9040e734cde5f6e9c8040500486764ada25099a9098d65dfd1ef66c81b4dfe98f2d04a461296ecaef195404f2793ed5a57 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/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. . Eclipse zenoh (pronounce _/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) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## How to install and test it . See our _"Getting started"_ tour starting with the [zenoh key concepts](https://zenoh.io/docs/getting-started/key-concepts/). . ------------------------------- ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.5.1), so no special configuration is required from your side. To build zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . The zenoh 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. . ------------------------------- ## Previous 0.5 API: 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. . ------------------------------- ## 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/*'` . . 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/0.0.0.0: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.: 0A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random UUIDv4 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 `libzplugin_.so` on Unix, `libzplugin_.dylib` on MacOS or `zplugin_.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 (`0.0.0.0`) and port `8000`. . ------------------------------- ## Plugins 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-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.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6481 Depends: libc6:armel (>= 2.31) Filename: ./0.6.0-beta.1/zenohd_0.6.0~beta.1_armel.deb Size: 1980852 MD5sum: 129bfadb708931c7e45dee986d8c63da SHA1: c50bf201118edd8d4ed4c0d9c964cbc5c2fa5a08 SHA256: 2a81cc0c82452b9ab7c989bbe850c9a705c4a555cd36cbcae7c1f6022f5eb35e SHA512: fbdf6f5f3a3b3a0d55f329c47896b05af98f0ae8e964b5f4d26c477b28cdf2e178f0d44cea8ed90f3ca8c2d73946ea090b886898b442c3bd7567f3bd583320bb 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/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. . Eclipse zenoh (pronounce _/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) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## How to install and test it . See our _"Getting started"_ tour starting with the [zenoh key concepts](https://zenoh.io/docs/getting-started/key-concepts/). . ------------------------------- ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.5.1), so no special configuration is required from your side. To build zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . The zenoh 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. . ------------------------------- ## Previous 0.5 API: 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. . ------------------------------- ## 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/*'` . . 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/0.0.0.0: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.: 0A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random UUIDv4 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 `libzplugin_.so` on Unix, `libzplugin_.dylib` on MacOS or `zplugin_.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 (`0.0.0.0`) and port `8000`. . ------------------------------- ## Plugins 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-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.6.0~beta.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6313 Depends: libc6:armhf (>= 2.31) Filename: ./0.6.0-beta.1/zenohd_0.6.0~beta.1_armhf.deb Size: 1981388 MD5sum: dad6f60946e1f033aa736ab73df6b48e SHA1: ca65ffd8bfc75931c0621965cf3adea42d1cfb74 SHA256: 30698a7f044bf28033ed75c1ae789ca944bc3a171a9be4cb636cf9b1cc911aaf SHA512: b90b9c5dc060cbfd6b769a031cbace35789cd9f4dba9fc926291ffecb064b7bfbdb5b627fd29f27dae6e2862b995ec3799b66badbfedbc6efe36f28be63d4c64 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/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. . Eclipse zenoh (pronounce _/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) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- ## How to install and test it . See our _"Getting started"_ tour starting with the [zenoh key concepts](https://zenoh.io/docs/getting-started/key-concepts/). . ------------------------------- ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be succesfully compiled with Rust stable (>= 1.5.1), so no special configuration is required from your side. To build zenoh, just type the following command after having followed the previous instructions: . ```bash $ cargo build --release --all-targets ``` . The zenoh 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. . ------------------------------- ## Previous 0.5 API: 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. . ------------------------------- ## 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/*'` . . 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/0.0.0.0: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.: 0A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random UUIDv4 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 `libzplugin_.so` on Unix, `libzplugin_.dylib` on MacOS or `zplugin_.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 (`0.0.0.0`) and port `8000`. . ------------------------------- ## Plugins 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-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: libzenohc-dev Architecture: amd64 Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 115 Depends: libzenohc (=0.7.0-rc) Filename: ./0.7.0-rc/libzenohc-dev_0.7.0-rc_amd64.deb Size: 23220 MD5sum: b3a87c213db4effe0e33612b3b3a940d SHA1: 95082e7a5de326659db2d58126269b04ac186b7b SHA256: 508c3d7d0f7fd050b9609589718a2ce7e7741fbea6cbe93390a2b31f173872dc SHA512: a7d785d0a262c062749927a95a4cca3c93b7e7481ebf8f53cc614d4072339e06f5bd5db1f78221e3e6c81402d065ec13898524efc846cf6580907ab2655a01d2 Homepage: http://zenoh.io Description: The zenoh C client 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: . -- 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 zenoh-c ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 115 Depends: libzenohc (=0.7.0-rc) Filename: ./0.7.0-rc/libzenohc-dev_0.7.0-rc_arm64.deb Size: 23216 MD5sum: 2318c5f9ca2891d0fcd01dc2a7f02a96 SHA1: 129056e93f75c2a83edc84cc6e0c62a6fd2b603d SHA256: cd1ee1a6cf28124cd2ccb7cbad6443f293001870e41e83f0ad7860e38b7ae722 SHA512: c6298c36652f5ec7663bd9e32448072d4f31e883d43e9a99aa3f97d91ee9245b233267f66be5ff87a99c62dba3a267b648882879b0bf097abfde05c81b792978 Homepage: http://zenoh.io Description: The zenoh C client 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: . -- 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 zenoh-c ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 115 Depends: libzenohc (=0.7.0-rc) Filename: ./0.7.0-rc/libzenohc-dev_0.7.0-rc_armel.deb Size: 23216 MD5sum: 58a6e9abe9c3701eaeaa68be4cf8e147 SHA1: 7192dc0b82c5c76beb5743e4e63f566fcf6df4cc SHA256: 0d659a470110147ef8dc6a441375ecdb07b8ab9e06414104c74063ce66ae271e SHA512: 29f4e9afd8224334ab45b8b9a194125c6c5f356332a21c3b55c909969c9bc950e6cb396d74f4b228df9d30881a398a72185a2351e1b13e1f565d21d896d5dbb8 Homepage: http://zenoh.io Description: The zenoh C client 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: . -- 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 zenoh-c ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 115 Depends: libzenohc (=0.7.0-rc) Filename: ./0.7.0-rc/libzenohc-dev_0.7.0-rc_armhf.deb Size: 23216 MD5sum: 785d11a382619baf35be6c5a2f94f6aa SHA1: 8801ea286f5abf692217644b6f8cdb1b2c65b1d1 SHA256: f895227cb5d6615f5fae65ad9cd115788b7007484061b9e807a3631c1d8e1200 SHA512: c602d5b45e41688adf3014b60c40d835c66b8a69503244dc1a05b0d39acdf00d2793381014c6ad5a6df50220fe89cb43f4650a953d636f5d7667ccdf3f27ca17 Homepage: http://zenoh.io Description: The zenoh C client 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: . -- 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 zenoh-c ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10357 Depends: libc6 (>= 2.28) Filename: ./0.7.0-rc/libzenohc_0.7.0-rc_amd64.deb Size: 2802116 MD5sum: 93ed00bdbee4e0651bc5878f477830a3 SHA1: 36184a4a37230cf1b4c02d0306230679cf302c22 SHA256: 14615f2ddfed9d31d6b16b3c1f6728c4f0d479600932bb54237effefed18d09c SHA512: 20590b07f636bd41c00fa1a80d97fb9aa42410d256f59a50566b570c820143fa80f8678036b6fc98e1134a33ec2f218c1be6a7cdbf59bd662c4edce64b234e52 Homepage: http://zenoh.io Description: The zenoh C client 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: . -- 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 zenoh-c ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9165 Depends: libc6:arm64 (>= 2.31) Filename: ./0.7.0-rc/libzenohc_0.7.0-rc_arm64.deb Size: 2478852 MD5sum: e7db37a94626fad25dd1af443116450b SHA1: dedcee7ec08021f301d25e05beea6f0864ca0c46 SHA256: 4aebaa093d262174e6c3daac9d56184cf5c83933d8f53844461075bf520bc55c SHA512: bd4f5e20a9d75fd90cf164273f5a99f58ecaf9c047b849c66aeaac74ac708a8534bcc7ddf5e15f237900b44f10e70014e3ec95467772ef2fa6da31d292e7d6b4 Homepage: http://zenoh.io Description: The zenoh C client 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: . -- 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 zenoh-c ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9448 Depends: libc6:armel (>= 2.31) Filename: ./0.7.0-rc/libzenohc_0.7.0-rc_armel.deb Size: 2549204 MD5sum: d78e51884c451a98796e8eed8003773f SHA1: a1cdbe598cf8335201f87efefe2314c3399113b5 SHA256: 3c48371cef7bff219b7f39e992fa4e2e80a353a332cf4afae974723347526a27 SHA512: d373ca5970f07bf9cb4c04480e5a01e64ef39abcd2e5fbfe9d5ea16c4bd1efc1e9af0b3eaac57c196aca640489bb80faba3c0f5d8f068a14bbe16589f871dc0d Homepage: http://zenoh.io Description: The zenoh C client 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: . -- 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 zenoh-c ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9315 Depends: libc6:armhf (>= 2.31) Filename: ./0.7.0-rc/libzenohc_0.7.0-rc_armhf.deb Size: 2555404 MD5sum: ef1723ba19b242fcedfd2659439dd1b7 SHA1: b46da96738969abef97df74066de2f98b71dca34 SHA256: 54d7621b5b86170f87e4f817c83c3bfa23c6a128154d5c74bda5602455d2181d SHA512: 0282c963f0f6602bcc9fe7c6612e110f31062fb2a18b25a90dbc8df106e4ff26fa7f4d8532ff5c13f4ccda2d613416c8088967ea00681c325c97f964cdc70e04 Homepage: http://zenoh.io Description: The zenoh C client 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: . -- 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 zenoh-c ``` . [source]: https://github.com/eclipse-zenoh/zenoh-c . 3. Build and install: . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ cmake --build . $ cmake --build . --target install # on linux use **sudo** ``` . You may alternatively use `-DCMAKE_BUILD_TYPE=RelWithDebInfo` if you wish to keep the debug symbols. . Note that the `install` target is only available for `Release` and `RelWithDebInfo` builds. CMake also offers the `Debug` build type, which we do not allow as an `install` target since you may suffer a significant performance hit if accidentally using this one. Finally, CMake typicall offers a `MinSizeRel` build type. While we do not prevent you from using it, note that it is strictly equivalent to running a `Release` build. . ## Building the Examples . ```bash $ cd /path/to/zenoh-c $ mkdir -p build && cd build # $ cmake -DCMAKE_BUILD_TYPE=Release .. # If Ninja is installed on your system, adding `-GNinja` to this command can greatly speed up the build time $ 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 `/path/to/zenoh-c/target/release` directory. . ## 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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. Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohpico-dev Architecture: amd64 Version: 0.7.20221221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 358 Depends: libzenohpico (=0.7.20221221dev) Filename: ./0.7.0-rc/libzenohpico-dev_0.7.20221221dev_amd64.deb Size: 48604 MD5sum: 12776f80ef5c6aea41535dc82c745339 SHA1: d994c6636174cf91440f57d21c422448d78e47d3 SHA256: fcd7ef2c05d33b2cfa66cb0df9231e5d1497e244cdbb04de1e4ee739de65942e SHA512: 12590f39aeb63321dab81256dd525f0a8bf6aa416866df03b1fec0d2b13cd87c93ceaf52fe0c39e2d358eb82b72534242e361fee7dd0b15fbbcc576bc811e9b6 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: arm Version: 0.7.20221221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 358 Depends: libzenohpico (=0.7.20221221dev) Filename: ./0.7.0-rc/libzenohpico-dev_0.7.20221221dev_arm.deb Size: 48606 MD5sum: ef99a8d7298dc7970ba6dbd968ee4608 SHA1: cf13104aa9cf95989187e56667d6c59d4e56cd3b SHA256: 63e14a145765403b921fb29ab5f0c6bb30b7e203779bf66c4d6afbef19573156 SHA512: a749c829d1a9f89ecce5979cb2da2314695de3be3acd1a6e5efe7a6de4ff34f4ea1591d32e8a89c00036fa9a51abfa5815f2c3c4e1cd99bf558edb6230fbcbc9 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: arm64 Version: 0.7.20221221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 358 Depends: libzenohpico (=0.7.20221221dev) Filename: ./0.7.0-rc/libzenohpico-dev_0.7.20221221dev_arm64.deb Size: 48604 MD5sum: 0ec0f7821979a1c290e46af962cf56d1 SHA1: c0ae1ad9c9c0f2c195406e74c14586c6da793a7c SHA256: a5d682479c9fcfef0fc4f3c594a2578a4b748bf12e7ad5dafbb8e3e1f693ec5e SHA512: af5f6c0e63e1c35f54a6e3a4675d04b9ac4d28e53209a1610aad87c47dde9b98465243b7874faad8bb17ede8c6d2f30fcebfc381710a10345d8ab78b78fdc912 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: armhf Version: 0.7.20221221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 358 Depends: libzenohpico (=0.7.20221221dev) Filename: ./0.7.0-rc/libzenohpico-dev_0.7.20221221dev_armhf.deb Size: 48608 MD5sum: 3427075fb2ccfc7f9b0da401a88d1158 SHA1: 5312994670376187c8dd07ab118a3ceff614429d SHA256: fa61e88859794d3ff81faee47fd505edde067ffbb61ed4eb60b0bcc44ba376e3 SHA512: 50768e99caf809e30de281a8c42ffb2330d022d01219780713fd02cf7b97db9ec8edab1075239cbac432cc4363bb0e44fefcefc521879d1e8340360d9e1737bb Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: i386 Version: 0.7.20221221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 358 Depends: libzenohpico (=0.7.20221221dev) Filename: ./0.7.0-rc/libzenohpico-dev_0.7.20221221dev_i386.deb Size: 48602 MD5sum: 3feb136375277b116fdbc66ca4a042f9 SHA1: 2697a3a3e181e9580b0d6aedc2da20a52237b5c7 SHA256: a174ea8acfdab162baf1c942850b3fb868f1ca9e44f76c4dc5cac5b259044751 SHA512: 6f5d49c9adaed392d50b41689cf0e226e8e9687dddf4d07bed969e225c93c440fea90e4f8e747d8f91c9a6f5fee45dac76d3d9fb023deda42852d3666781fe80 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: mips Version: 0.7.20221221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 358 Depends: libzenohpico (=0.7.20221221dev) Filename: ./0.7.0-rc/libzenohpico-dev_0.7.20221221dev_mips.deb Size: 48602 MD5sum: ea7335a96492c7b98a836cbbb452c7ef SHA1: d8ff442c20cb1031ca903a28169cdf46482ae66a SHA256: 845d8a96acb2093413ce21f95de256cf641d6ca5536f9f2550f17c6e0d557ca7 SHA512: 6aa8a4bc84c09bcde0ccac95c0d7e85436a33ea3de0700e3ca55e6d519007fa9e7c474f827b05331932dbd3a0cfe2d71632c13b8ebf2bbcc5f71339d7e8d9b8a Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico Architecture: amd64 Version: 0.7.20221221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.7.0-rc/libzenohpico_0.7.20221221dev_amd64.deb Size: 610 MD5sum: 5ac2ab8e131db6e53a637eeeb75f7cb4 SHA1: a9411269770ff19712dcbf74bf362a73aed0643f SHA256: dbc0aeafcb40edd20334e0730146b47f6aa17ecf8287a8daecfc2157a3376aad SHA512: 1f8b2013f02ffae4e1a315b5e3c9a803de23b4e5644f0cae02a17be6a1a8d72259050d31fe2a9f81208b6270341022563e681e051afa348c9df85eb70cf45a2e Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: arm Version: 0.7.20221221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.7.0-rc/libzenohpico_0.7.20221221dev_arm.deb Size: 612 MD5sum: be00f0f47e8cfd042346f8ef3063a51e SHA1: b148706b9bc252b64696f6ccab3ca2fef12e7b0c SHA256: 711f855d70925377bbd525699f3874223d978146354aafbfde1cc53fc5a0d79b SHA512: 99e4b4e320eec9f83bad46ba6f4926c4e3333889dddf3c92e8aba9ae23c20b47bc4834cbb01d5ce6caf64acee0cb14b4fcc5db420cf3a0a82d07032f0677d913 Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: arm64 Version: 0.7.20221221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.7.0-rc/libzenohpico_0.7.20221221dev_arm64.deb Size: 610 MD5sum: 4f542b2ba0eb0f60996e7c181c96c217 SHA1: 055190b3b29d2904a04df72491f0c2e6e1fc8484 SHA256: 897a3a802f44992980986d9a6f1d6a4bb221d898585d9d9beedf1df8569f6398 SHA512: edfa083496eaffe8de0a651d172d2bdc530dac12bc6eae13b2fbd8020cf4d53aada563403e8898ef85b8d0e27d6d9a92ed555b03e5bf0af87b9e2af78813354c Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: armhf Version: 0.7.20221221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.7.0-rc/libzenohpico_0.7.20221221dev_armhf.deb Size: 612 MD5sum: 8f6f7e8a4ed8b7e38d7749b1fe5b301a SHA1: d456ed5b28b8acc8a39e7735afcb39f4578fc6dc SHA256: 86a24b2422a5b58b1bd9c374f6fa362b29d771424b9530c5eb37f89b9985bb48 SHA512: 0696753144f37a07cca8f66a8c987b10b34c6e1229654eeb2fe1cf5ff6a7aa5aacf0172643c9f5237ff426c8722cbe097626a31dc0a067f9da69cdde99da42a4 Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: i386 Version: 0.7.20221221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.7.0-rc/libzenohpico_0.7.20221221dev_i386.deb Size: 612 MD5sum: a2f91f9cd89c35894677b14ce7e6c5ea SHA1: 75e0a177d7e997c6a692978bf030d26a2c3e2dac SHA256: 532577f3752013424d300021f699d0bb2668e54a4cc42875470947110339d8d0 SHA512: c60043ad50e904a5d66ae828271f78cddaccd05c604e1096c51027a189e64774251e6778b9c781a2032bc86b8ed842128c5354bb532b39ad351202dee43aa03f Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: mips Version: 0.7.20221221dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 4 Depends: libc6 (>=2.12) Filename: ./0.7.0-rc/libzenohpico_0.7.20221221dev_mips.deb Size: 610 MD5sum: 2f18a80bcba3009e57877d07f5e46816 SHA1: e8104bc1825fe951fc3b50478e1ae048ee06eed4 SHA256: 13d8146e66c6dabbe559cc28dcbe569fe905c6be9daf258a6af42189e366fd16 SHA512: 6dabd483a1560eb3489ba0bf68a3b92294dac8f57051745a1c5b793fe2cd8a7560fcce32356846a8fad677b019bf6e4c4b235cbed43937ae4cd1873acf4b0f8f Description: The C client library for Eclipse zenoh targeting pico devices Package: zenoh-backend-filesystem Architecture: amd64 Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9058 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-filesystem_0.7.0-rc_amd64.deb Size: 2742356 MD5sum: 427401313bd3ea45f4105cf21b957f44 SHA1: eca152ded035145715852ce163a63e7b1f17587f SHA256: 85adeb43da5ff12f621c8874dfc6c8761863bf6865fef4e06529754be4eaef69 SHA512: 7ca470f1a511fa097f1eb925a78e50898886812782c3a76c3309aae494c53b8b18167ba2b230503eeddf649e655b03180472fcc121b36e1becbf0f7bf97cf946 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8011 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-filesystem_0.7.0-rc_arm64.deb Size: 2391684 MD5sum: 7452feb5bf656879dcbd8dc0470fbf6f SHA1: 16e4da450a6ae18a92c62ed7d2462b723ce6444a SHA256: 4db5d7dde17645277687cc7526a7ed97cf2894b779d06a8c1e0b25023ca14b86 SHA512: 2818dc59a610b556e380a4afd5f5fb96b63e14a1e4aeb295954d0ef06ac8a6071359a11ed69cb2a94c2df7971cf6191cd17e290eaa3a44167754876c9d877ab3 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7657 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-filesystem_0.7.0-rc_armel.deb Size: 2320948 MD5sum: bc6b29fde4332bd98f15c7b752ba2a96 SHA1: 5f5a3d64124200bbc56482b7fe75a9cafaf75094 SHA256: 7b66e0438ac938e023f55ee12d72a14bc2cea4346a1b9a3502b09ca35f45852a SHA512: 042e2f4f39ca53e67b2a13839ef4bd582fc9b2d64db164fd1c67089dcef881d02977ab8d87f092ab4b83d756cef4cac30a25fefd7c7bbbf01fdfda7cb0a9025b Homepage: http://zenoh.io Description: Backend for Zenoh using the file system 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6009 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-filesystem_0.7.0-rc_armhf.deb Size: 2398372 MD5sum: d12c78193373176fa48f3d8c28bcc134 SHA1: 777ce80e1d8ce275251abe66938f84e411be804f SHA256: a484c31c71298d580bd76521ee914a66b942fa2e2537fbb725446099f974f5fa SHA512: fa04879616372805af01e828913a4ed07bf7ca44f4ede55077364fbb16dc0900c0ba11c1b9dc9c1902e06824869264ca22ed943f14faa7bbcbf079742a0647b9 Homepage: http://zenoh.io Description: Backend for Zenoh using the file system 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4938 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-influxdb_0.7.0-rc_amd64.deb Size: 1525336 MD5sum: 66faaa994b739be3511183959f030272 SHA1: 06eddfb3917d984d21113c08c05d7377785d9766 SHA256: 000a97127bdbab199165328767e75ea1527df659be779f07e054708f7c4db685 SHA512: 32cc511107ef080e22bafa8b51bc2e1182f43ca5e8ff230f248b236e96ca9600a965983bb81a3d1a912d71e694011ecb68d7ec1f24e302ab8b01db51eddc84a5 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4474 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-influxdb_0.7.0-rc_arm64.deb Size: 1359060 MD5sum: 1d79b3e97e4932f987d462c4e564d96e SHA1: 7541febe7adf9615eef337b263f3944316fd2ca8 SHA256: d205739bc69047216a4379b083a3179719f0c66dc0410591d5f42c7517d3cc08 SHA512: 151fd2321754619e3394745c444ac72491d7f23e8c04fb97c8885c10709448bb907f472b47fdba5591b646a3ac842ce0d933ac49d6d40c37eadbdc248801a1cb Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3937 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-influxdb_0.7.0-rc_armel.deb Size: 1148012 MD5sum: b6628649447c80a01762e06dda89744c SHA1: f4f07e3af993840292f7e4611c5db3eae5869fb4 SHA256: 740ca9802845b5b3858ef654df50253cb6da4b76b84bd5f4eccbc4a7144aa0b6 SHA512: 2d764cfe713e063b3bccdd23b74e55da8070330295d89c5817e016c264a5ff2af342c77cf853b3a14ecf031df768dc7c853f7f6b60382ddcb3d8faeae5c0d036 Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3849 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-influxdb_0.7.0-rc_armhf.deb Size: 1143928 MD5sum: d4bf5f2b4cf445ea8930c2b0366aa177 SHA1: f3b620fcb1c56719d2e1cad59d8882cb73f4cb8e SHA256: c2c60df4252a7d35aca009328cf2a55a6b625b93cbfcd5d7b1f7fa264dc75b9e SHA512: c18334f8cc25817ea126e67690162a85baf2a4b61533e83ca60e8e04473225687fafc36b346fd6fd7d4a33700b022d6c42d5840dfc71b0fe0845fa47273d2a1f Homepage: http://zenoh.io Description: Backend for Zenoh using InfluxDB 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8934 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-rocksdb_0.7.0-rc_amd64.deb Size: 2715164 MD5sum: 85f3c0ddf4314c996dad249eab8928dd SHA1: adcb4a9c2c1e8e65fb2a6a40c9037943e1053051 SHA256: 99692e5a660b34d060d14e2d15b0b250e34bc64b4d4bd85376bc4c93bed15552 SHA512: a40e33ecede219fa233a45b03fe20e29727aedb5d693f7788a338f7282da1c1d2eb69d4d5fccb83dcd432cdbec837225737369c6a68396cc8703ba0a363f68ce Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7891 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-rocksdb_0.7.0-rc_arm64.deb Size: 2364216 MD5sum: 437cb62d03eefbbcd01435f078267915 SHA1: 4de3ae93b4b33ae76d25cfafc01c32fadbda99a8 SHA256: 09d9472da8bf3cd14aea468b22729c0cf1dfcc1a3a27af709a89b03320a05fe3 SHA512: 1781f6000c8a9f7657fb1088c711ef438b78aaf9ee8dde6337f1dd50d5e11c7dfa3a12ca02b1c5c849d03b6f8d6d8f716207b3638eea9aae95dcabce9c081030 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7605 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-rocksdb_0.7.0-rc_armel.deb Size: 2301972 MD5sum: 92ffa22727deaebc48c67bac3df5497f SHA1: ffe5771659c52d704024e37981776d46e6968888 SHA256: bb9db05dfb4e06fb7ff9950f93136f9d6d17d399deda5112769c818b4df83054 SHA512: df06ad8bb83a439ab07fadacab4f91be880b9d80a44de0d3274cb1d9f99af6d2b015611be5e49106feb342512228324a3367273d12252e0a9518996e43a68043 Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5917 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-rocksdb_0.7.0-rc_armhf.deb Size: 2377568 MD5sum: 62c0d3010cd84e256e4658570c736c9f SHA1: e34a7249bf73dedeb1edbd85d084dda01114f031 SHA256: a08a415be6058e108a4df78716fc766f628befe9396e8578a2d75c7b0ffcaa2a SHA512: 47842fa043c6465cd1dab29acd67c4d6d0a44b4e6f30b1e885ba8bc62a85080932ca760afb5f61822daf99229a9050efe231a43eef6dac62673042d4d83551ee Homepage: http://zenoh.io Description: Backend for Zenoh using RocksDB 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10986 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-s3_0.7.0-rc_amd64.deb Size: 2747280 MD5sum: 792bc204beff7f776755ca38ed3c8792 SHA1: b52e7150e0ef1263cf66aa8aff84408dc7c1e8c5 SHA256: 5347b6f211d114e8245b6f22c53c62a2011addda15361d4194823145070a4bd4 SHA512: 4b74b7175b8194c7ffe763563245b48f96c180b9191e6e03a1ae7211257925e26f1eaa5195a244c8e2f8d6fead4907fb776b35d7d252e2cabb911593f17029f1 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9806 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-s3_0.7.0-rc_arm64.deb Size: 2470960 MD5sum: 5b2e300564c4db2acae9928e6695f9f9 SHA1: 4bcbddc681726057212d74e4e342fe6b46763b1c SHA256: 2cf89d5b1b5438a80b520d80bf02c67a76cf5db9b94c5b55864b01e1bedc4281 SHA512: efcab3b7dc5e76211cdbf78bc2c89ad7ec5a3df986c1c317912fd9fd4eb1280f0132e22b01f78bd2b36e60ffc783728ef5972dcfb5764266d38a24857e3d5a67 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8723 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-s3_0.7.0-rc_armel.deb Size: 2147588 MD5sum: 0b0148f2132eceab9dfd5e8812fce214 SHA1: 06e7a6d623dcdb680319efc89a7e5009a02163d7 SHA256: 8b48ec42dd096d5df798b769a4b51560f8ade6f34c1506a6124292def6b12392 SHA512: 5f3dd43243e9ffe0c481ae7c815060db2557327dd2fea13598cb01cf36fc1a57b56d13773a61d9b23e7abcc0fece0cfed828d95d9c1c75cdec262948c7c368f3 Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8563 Depends: zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-backend-s3_0.7.0-rc_armhf.deb Size: 2153356 MD5sum: 18deb66c54551e3e175c95af4942b5c6 SHA1: 1a1b8cd418936e95c86868321378c6e8f8263753 SHA256: 569b1471ed45ed81e1e70ab256b7a19d03ac1bf7f3d556d3145d767dffe0496e SHA512: 84dc0d916649e40238c152ad6799040471b1e5f72ed845403873cd227a17f3a32ff031c3865347b2a705c4d3de264cf72177dab06d224abe398c7d6be0281b6b Homepage: http://zenoh.io Description: Backend for Zenoh using AWS S3 API 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9174 Depends: libc6 (>= 2.29) Filename: ./0.7.0-rc/zenoh-bridge-dds_0.7.0-rc_amd64.deb Size: 2959572 MD5sum: ad622f69ccf722f67ae70872c3b05f54 SHA1: a4da5c1ffb03e884315d21e8e3f3032660616e6a SHA256: 8642a9d9f6da5a08362ffc0ff53091c88dcd9929ea0a35b820195741164edbfd SHA512: f1776ac6b286249f806912857588ba30eb109a1b79489a63c7a628af82498e1b687e96d0799dd25ddb963e95c6985ffe5bc48826c3a37e85b58a210134de50b0 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7921 Filename: ./0.7.0-rc/zenoh-bridge-dds_0.7.0-rc_arm64.deb Size: 2652588 MD5sum: 251e98f8e3cd60ce9febe699fdac0b4f SHA1: bcd4d405f6697969e9e5e7043442157a20e24541 SHA256: 6ecc1fc876bcceae1377f178bb44d0abaa0599f0642b3284bcacb004b3cc8b51 SHA512: adb62c9df689d924ad6ce97498b97f63a265204c88e0215c6d1b69cdf807f7b32f8ffb37afcc8d25d363136ffe3a73ac3148d0b826304c3954b851f5b37deee3 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8072 Filename: ./0.7.0-rc/zenoh-bridge-dds_0.7.0-rc_armel.deb Size: 2573768 MD5sum: 53643143d19bc02f937fb50d264a5cbf SHA1: b129c7c88d4243c4e19661fe6ce9d9900a26cd67 SHA256: 8c91a529767dc30fd309b3e2bf87dc42d35c4c2ef077e6f5406acb4312f52f99 SHA512: 08f7a663b7ed62d03667cca1fbb49ca4b3872932fda3b4aff12dd3d0bb2a53569645bed47ab471d12bbe0ee9871432629c515ed44e59b3da449ae7ff4c5b2d74 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7668 Filename: ./0.7.0-rc/zenoh-bridge-dds_0.7.0-rc_armhf.deb Size: 2590408 MD5sum: 49c93609da58aea057eda06d53b60687 SHA1: 6fc8a6228ba300768bdbbb31cbdc50ea6f57f049 SHA256: deaf0a683e7408361572c5deb468c291b76709b81e9550a8333ec6ecc5fdd7b2 SHA512: 08bf38811291b97bd5a879adee5ce2ea6a3acbafcef0935d90f7bd45f459786f40dd4d5eb2e52cf33aea86bf93be4f9ac155b23b30ddfd6d1dbb9726ef8fa767 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8277 Depends: libc6 (>= 2.29) Filename: ./0.7.0-rc/zenoh-bridge-mqtt_0.7.0-rc_amd64.deb Size: 2648100 MD5sum: d652bba7451cc4a58316c2a89feb0cc0 SHA1: 0bb859bfac1f0081474f5dad582537b3c09a8c8c SHA256: 223ae968996e50ac46e550d36d01155502590d8cc9c1cae8c329f30db9273edd SHA512: 903d3294c703c99a337e96b8cefa0c47555e35af5e6a26dfa4dc10d3608a22a262bbdc0cfd1fb9a90021b19c194e813882f5a5aa4f8d0ad0e1b02d5aaa3b7c9a 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7065 Filename: ./0.7.0-rc/zenoh-bridge-mqtt_0.7.0-rc_arm64.deb Size: 2359492 MD5sum: 90ef64263a3c60ed0e7853d07589e44a SHA1: 96243881101c495c9dc8da89b7cf80aa4909ac38 SHA256: 570f8b350c0564e73cc215c53cb53361657f0b30ce30b57c41b5d99a68362cd7 SHA512: bc2f62110e3698d2e20f058623e5015df290cb365dd9d88fdf9f3c509b325d4d7af01471846525200fcd01519f9b06bf515cbf4a546cb86a59a0e797c649ec8c 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-dds Architecture: amd64 Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4076 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-dds_0.7.0-rc_amd64.deb Size: 1213400 MD5sum: 1da523f4e75f6f0b08cb19acc8d9615b SHA1: 79daae99b983e3db39d877554b2317dbb02d74c0 SHA256: 08fd7a3fc60258f77abff128d37e5f14ff953a263d706960265005b29435ef8d SHA512: dc8c9c8c9064896e606397996ef99fcfa7234a6c3abafb744f3fa4256047f5d21729b16f860fd892d84c49befda9065aa793f74f07e23b42c7b0335a93ecb021 Homepage: http://zenoh.io Description: Zenoh plugin 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-plugin-dds Architecture: arm64 Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3652 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-dds_0.7.0-rc_arm64.deb Size: 1078136 MD5sum: 3156709fd3ecfda4920d63321d76b29b SHA1: e37eb306e0c9bb2a82bf86ac0fdc5f1483b7e86f SHA256: ca428283d68d767dc7e9d2233126358b63b81accdca59f69379b73e896c0719c SHA512: 7e88ffa27c46edd41b216f492a9a69d88e3ff5cb0d0a7c0d81411b568c8a2629c25940b32db0989bfaf4b2cbeb0e68d7074c9a9cb0e4b894c6d0b4abe2f6a0e9 Homepage: http://zenoh.io Description: Zenoh plugin 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-plugin-dds Architecture: armel Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3503 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-dds_0.7.0-rc_armel.deb Size: 1048948 MD5sum: b49451cbc6099ebb980890ec5690f4aa SHA1: 5780dab9c110639c576e77eb6f952d11b17abac2 SHA256: 6f3a518b6718e4d28a6d8ff40bea841c694d40410b1781bc1b9b10bddbf29650 SHA512: 4f0c28d001e6867388581262a2a10bdadc41d59c00c08011b57571bc49f82a9f6680a878b0d344a24b52c51b0c31a69d305acc59db2057a3fd1c149b1eca1617 Homepage: http://zenoh.io Description: Zenoh plugin 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-plugin-dds Architecture: armhf Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3223 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-dds_0.7.0-rc_armhf.deb Size: 1058780 MD5sum: 2d12bd9cc0a8e46c1e765e70a48a0885 SHA1: fe245a2facd4e8b121241d0ce8851c7e78f99f19 SHA256: bb30c701c863203243ba315d6dc9ca503b14797808d018fbf775d1bfccbdf8ed SHA512: 8d55acf5bcd10fd670406eaeedbfa611dfdac3527f810fb6dbd761440c9d37e1d91e7de3facc68ee5c298a96e3476d7f835faf2ff99dfe242184e7e383cbeab6 Homepage: http://zenoh.io Description: Zenoh plugin 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-plugin-mqtt Architecture: amd64 Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3194 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-mqtt_0.7.0-rc_amd64.deb Size: 899012 MD5sum: be9241bb2575af2c855001a8dc9fca80 SHA1: 5031400c58e63dadc4611f08b1e7809f5cc3c905 SHA256: 6106c6a8a8a6c386cc8db0767c3c0fb39f2473cf2ae96eaec478a29fdbd4f642 SHA512: aa0460ab18a41f91ed1f2a01eca58a242f748f45f3b48802cd65c12409fe41c6200afe17e09d56942382d523a9fd4387a4f146a581e267bc7f2c7f69fc0d57f6 Homepage: http://zenoh.io Description: Zenoh plugin 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: arm64 Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2802 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-mqtt_0.7.0-rc_arm64.deb Size: 780372 MD5sum: c1ed6276f1bb40c5b8fa25bc480d5376 SHA1: f57e12a21e0f33cab422ab00713ad72a9821d536 SHA256: 19b30afcf01b1d8039a8a03a560adf0d212f46a729c4c397e104f27e595a2149 SHA512: de886305c2f1f00117d788b722692d0c37cadc95062f773aa9630f4bae11c3e7e5c12ade1a8d207fffc4feec9eebbcee44b48b7179cb415a785a191d9ebf6fe7 Homepage: http://zenoh.io Description: Zenoh plugin 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-rest Architecture: amd64 Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3210 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-rest_0.7.0-rc_amd64.deb Size: 916224 MD5sum: ee03a17e5bb39c4fb7d33d04f4d0aced SHA1: f996303333320c0e7c14ff0a9ee26e4ab7c1f1bd SHA256: b3b63fedcab65833171dde9692b5c55f526c65cb7d9ea060ae0d32796040f8aa SHA512: eb0103f7f344201a840ebaf46686c38afaf16f459b10bfb5b94b784b4b5463078986d1dee1e884db585a6cfec05888749216099f67d377bb084d2d59c137919b 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-plugin-rest Architecture: arm64 Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2846 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-rest_0.7.0-rc_arm64.deb Size: 806356 MD5sum: 5181e0b3fe8fac1d5d3ccf329c3fdb82 SHA1: e0a6df0b952036de604580d44a5690a144a9bd90 SHA256: 20f271adbdae2458afa1e140ff567ad3318e32a6c1c07a6e81ba3a6a17d5cbcc SHA512: 85ec4603cc27e2096febf6d5d718008300b01c2b54fb5fe6e9b8b2e5d202b78ee16d2ab2d605d0c2d90cd71013d2749eb51797ac454b728bbad6d8e7b92585dd 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-plugin-rest Architecture: armel Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2765 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-rest_0.7.0-rc_armel.deb Size: 802520 MD5sum: fa5ef5feb976681e949c0df7fba10b1f SHA1: 9b2f453318bc3e293e829420d224a2b43de0309b SHA256: 3bc19155d64899ee28920c68d9b4d6beeb3e18ff7f795160135e1a03e43cbba7 SHA512: 8cde129892efc2f4f471f607743fd79a64f6133924a161cb4c7bd0ece7709d428a7636ab9888b07c737c33076d74dfa5c3a16386c6532e6effcc0959c00b60f7 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-plugin-rest Architecture: armhf Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2709 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-rest_0.7.0-rc_armhf.deb Size: 796356 MD5sum: 6b6979fb58b4f07714f9e170fd60991b SHA1: e8bdd487139f90b6a23f55be25638002ba9cc5bc SHA256: 9c5dfb41616aee1bd34a992ae2f3473aada67143a06aa90703b8cb54aa9d1de0 SHA512: c36df42810f685d479e246cb8c3545447794739807af221df6045eea738bc677f85302f36271810909448b425b005fde21478e1c2730d8b4110db6a590728451 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-plugin-storage-manager Architecture: amd64 Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3170 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-storage-manager_0.7.0-rc_amd64.deb Size: 891748 MD5sum: a7b1670f23f926ca20265aee46503e8a SHA1: 99e418d6eeb0b2c1101f3e45f16ca38810c778fd SHA256: 62fd5b5f662f8c6dbd7caaf4a4e8de8f71dd92fd4f980ea8b81c4f230878f629 SHA512: c0ca7b7fc670712af34dbe158c8cdc8ec8776841d7dc40429a4dc44d8e4bfb575a289912b34c2ab68c6bda216798f71cc31e43195122f474217bea4d35ac6f29 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-plugin-storage-manager Architecture: arm64 Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2766 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-storage-manager_0.7.0-rc_arm64.deb Size: 774748 MD5sum: bc1fc381153681314d349ca11e0479eb SHA1: 031511c7ca9e720e2dd372697f497c1aad347e7a SHA256: 5851e5e913e7abfd68c2701bf806fc330487759b33fb9b44c19c474067a9fd48 SHA512: 05c9c11b4bf8a209daf89e2c81c429bebb97bb2581fc5a37826fa8bb13c5a778d0cb238eeb0dcc85f2f086b65259911ac60a1c09f4d177d8a8bd8b8fdeb1fc07 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-plugin-storage-manager Architecture: armel Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2721 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-storage-manager_0.7.0-rc_armel.deb Size: 783096 MD5sum: 849764317289c3090722fbf5f5e140ec SHA1: c2e211ce27c9d9983acbba634332fe351a11d165 SHA256: e2e6f96510d2ccdf46d83df1607f1fc26397485d16653148d078f5a48c411a29 SHA512: 6734f74ee797dd08d35c862036710e658475457b5b61d9945e48281c8438554d94eda3e0b85d521fd3a07ccdc20cf1603968654564845746242ac4dfcd5e4af0 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-plugin-storage-manager Architecture: armhf Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2661 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-storage-manager_0.7.0-rc_armhf.deb Size: 776108 MD5sum: 80440c49ba92597d75b3c8b6124afaf2 SHA1: b897317caa92f7de3f19c70034d6a40ba5dc047c SHA256: cd15117da03b7e1dd48b8a8d9ed786bf62067c385d868afd7f2591c8c5476a59 SHA512: cd6b66e7eecd9f31bc024bcc86fca1936ad470871ece8d5e6eff00404f6cb54a54985e360f8d6ae079245d57dfacc6c486b850b9f8aff7054b0b8310a17169df 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-plugin-webserver Architecture: amd64 Version: 0.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4390 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-webserver_0.7.0-rc_amd64.deb Size: 1182512 MD5sum: e5efe1817870a5b53c02b4d5316d2776 SHA1: a1b6a352f8155e0388445a285b0d9b135922e2ab SHA256: c2a065a8913026e6549db0484b00224ed7384a8e26e3ae8f543473855c070c87 SHA512: f9d2f9a386617c289765dfc0a7fc52c86b3e997d092688d74a2310b925d14e91d60fa81b595a9a5c85efaee3a3315af3bde95e9a79ab8707f0a6b2b9d20aef94 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4162 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-webserver_0.7.0-rc_arm64.deb Size: 1064200 MD5sum: 1a0bef27a3b5ed08c820b06ef564c79b SHA1: f38e4fb04358cb27527a409f0a7a8ffb6ce2c71c SHA256: 77e136161ce42761f271f5863ba5624955d70d0da3d5595b51ddf909a071bd65 SHA512: 518596ddc7e3995827f815106b4acebcca55241557802e05a26a257b6a11afa4f8bf037815a9355981258526621232100eda2f8db1ff487db327b749d07e0857 Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3769 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-webserver_0.7.0-rc_armel.deb Size: 990120 MD5sum: 3a10bad34ebfec749b788fb016b7b11f SHA1: 0ec4bfda0da438ae0c4c8370a8c73a2102df0ca2 SHA256: ff2292ce822fba5f7a8fe5372ab1bf1cac853acf3e20515b5a4929922ec6d67d SHA512: ba85f5cb08fed9b741bc7146a1eaa75c837ed1153acff5930d7669d8bcecdf06a6f0fee81d9492c5eb5596aa83bdf37dc296ea4e9d02d3c6df2b8b647682692d Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3681 Depends: zenohd (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh-plugin-webserver_0.7.0-rc_armhf.deb Size: 981260 MD5sum: ae79fb22a8166c9db7c0fa9decfacf61 SHA1: 52cba97c757fb961f2c756a69de5d4bd0296cd24 SHA256: 44ada5a965b4e314bf6a66aeca23eec85c35c848a4316a33e6a7d562fcc69645 SHA512: 683bc36530b07ad93cd262ae9d2a11dd7400eec92b1dd67f3ef77c3283f698e52770dd54535e9a64f718e1c85a9ea1a47d935f8c66fd14797a95845e5744fc1d Homepage: http://zenoh.io Description: Plugin for Zenoh implementing an HTTP server that maps URLs to zenoh key expressions 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.7.0-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.7.0-rc), zenoh-plugin-rest (=0.7.0-rc), zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh_0.7.0-rc_amd64.deb Size: 832 MD5sum: d2bd5b3944cecb0bee394ae604b3ad83 SHA1: caefe319bb146e121e50af8c65a8813339ba9520 SHA256: 8cb8dd71feb8caf1c756de1cfdca2686d2ec9df6e749fb33c94bac12c85b9785 SHA512: afe1b47993359d04310e09e3c36bde3558f5c020cede73f7d0aad2368874142fe73cb0d6301b81cb72a3adf84118b2efec8f3be96bfed74da5e45930457101d5 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.7.0-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.7.0-rc), zenoh-plugin-rest (=0.7.0-rc), zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh_0.7.0-rc_arm64.deb Size: 832 MD5sum: 5696a85649ad1faa3732e07e4303f772 SHA1: 5e1767a5489c95da3c4e46ec584c92d0fb03fa19 SHA256: 776385ae4425481fcdf84fdaf4938e3a9ce8ff8b5772676df7e2f04c87377be0 SHA512: 77a49e38e8657c99f03caada298c86b0122114aca5933c30d7d9fa959737d2537824ab4bdf89f613eba497b8715199252ae624c1f7b69d8ce3a4ab660397dd9e 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.7.0-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.7.0-rc), zenoh-plugin-rest (=0.7.0-rc), zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh_0.7.0-rc_armel.deb Size: 832 MD5sum: 82987a5627a1c66f9e822e2c7fdbd677 SHA1: 9153af98f1fa817a01878db88f94417b886e6c93 SHA256: d33636f6d1d78bdec147a9003ee6918ed8c5868e802136e2e5e05909d4030a40 SHA512: 66eb78cc712c0a648b9bfdf94e67cca1d58c2c30632e5aae8e196b5abfc0f7e12195931a05a4c02c724d143a439537326ad8e665064516aa489058f50e802732 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.7.0-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.7.0-rc), zenoh-plugin-rest (=0.7.0-rc), zenoh-plugin-storage-manager (=0.7.0-rc) Filename: ./0.7.0-rc/zenoh_0.7.0-rc_armhf.deb Size: 832 MD5sum: 72572384ffc7462b31fe5486f87eb684 SHA1: c270b94b67483d92df9ef7713d2f5b4c40b3b3b0 SHA256: 327c88da9636726f408534cec6cfef6a0d00980dbef59f1bb73db205b8208429 SHA512: 1df615fd9a74a4a1e2355b77c7334334863991e8176c54791cf4773052d227e341691f8e8f7db5a55c9622cb8f37f31a640886aeba0af2239f006c609e34c428 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.7.0~rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd, zenoh-plugin-rest, zenoh-plugin-storage-manager Filename: ./0.7.0-rc/zenoh_0.7.0~rc_amd64.deb Size: 828 MD5sum: 7dd692194bf30ece0125d49b2968d5d1 SHA1: a4d0b1ba4a662eb3267a99e00e6601fcfb203d09 SHA256: 07b8bfb464edd53036451755ceeb643d2f4a36576f637c692de4d14f349a0a0d SHA512: b92005f18c52b9242bc26b6363b2c248c8d25aebc567f1a2db649b1bd1beba53f09fc94bf9d8176503026cedbe7807e4cf8b607276047e19526f509424a4d492 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.7.0~rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd, zenoh-plugin-rest, zenoh-plugin-storage-manager Filename: ./0.7.0-rc/zenoh_0.7.0~rc_arm64.deb Size: 824 MD5sum: b6fe045908c500af88771adee0881b28 SHA1: 9291a2600c827df105beb117b0b5bbd10aab9c24 SHA256: b9e83151b16862da1d0e3807ecd09e6e4a5768585901f61fb6e4e66dc9e60f3b SHA512: 6b510a984962c2602179738bf946a42166a36d68df58078d3630ce7bab7ccee79470e71886849ca2f5c3198a376b833ad3d7c2059faffe2c0408b763b7e53318 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.7.0~rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd, zenoh-plugin-rest, zenoh-plugin-storage-manager Filename: ./0.7.0-rc/zenoh_0.7.0~rc_armel.deb Size: 824 MD5sum: facb0383672cf7d86d3bbbb3966e3879 SHA1: ff2dcd1007290d53ea4a9258fe9abd316ab7a9a8 SHA256: 1d1a47d7ff6698a2d2b586de59ad1541454398bb778630bac2ac5662fe75bb57 SHA512: 0aa0a0b6f0b20cb3152df05b92fea41ba4f9987195e83cbff144a90623ba8a2b4f01c49320b7986b2610d3c9c7165f374714f0b8ed17119fac00d7fc5b7aa534 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.7.0~rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd, zenoh-plugin-rest, zenoh-plugin-storage-manager Filename: ./0.7.0-rc/zenoh_0.7.0~rc_armhf.deb Size: 828 MD5sum: 222df8a9e379a984818d56811b5a3c58 SHA1: 6a3a4398eaa8ad6c0014415c9e122274cb52e01b SHA256: 2a27886fc0e9d9456ff24579119c96c66bfc8d28c3c7603d691ac39b8029d4c5 SHA512: fefcb7e7048c51eb39b5317ea1876035683010b621f5b7e5b5689a27be138a6c420750de2556857f7c09350862f0c21a1732ab2e73e4f690e6dbabaa49368521 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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6945 Depends: libc6 (>= 2.28) Filename: ./0.7.0-rc/zenohd_0.7.0-rc_amd64.deb Size: 2209372 MD5sum: ae0c195da70b3a0fde9163c58133f090 SHA1: eaf19324be6ca2557a5ca070e82eeb48befe8dce SHA256: 27fbf4588d97d9d5bff0281ff6ceaac83a4c7e4f6e1245da824f96a969de68d8 SHA512: 054f60c2ad532b04c1375288a65fe80d22c857bf195ca8aa96a8e6c8bf31ab1b35ef83ee122debeb6cf0fcff39188783e05f366869ab17d920429b526066af67 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 > /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.62.1), so no special configuration is required from your side. 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. . ------------------------------- ## Previous 0.5 API: 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. . ------------------------------- ## 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/*'` . . 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.: 0A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random UUIDv4 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 `libzplugin_.so` on Unix, `libzplugin_.dylib` on MacOS or `zplugin_.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`. . ------------------------------- ## Plugins 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-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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5857 Depends: libc6:arm64 (>= 2.31) Filename: ./0.7.0-rc/zenohd_0.7.0-rc_arm64.deb Size: 1956868 MD5sum: 3f6ac79e4cbbe6e6ae3f5d77330b0980 SHA1: 386da910ed3ee53bea74c8bebdbf06e5ccd54669 SHA256: 8e7ffc4eacfee283dcb372af75dded8c4ac57095e9842d6126d109e37e629d36 SHA512: 5999275eb73d339827242b08b31c0f1273a6efeeba872025f2e669e21e73b91f08a0ae7183f781772db57258a8126b893f7c626045635cecb911f0652a1d6a33 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 > /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.62.1), so no special configuration is required from your side. 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. . ------------------------------- ## Previous 0.5 API: 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. . ------------------------------- ## 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/*'` . . 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.: 0A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random UUIDv4 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 `libzplugin_.so` on Unix, `libzplugin_.dylib` on MacOS or `zplugin_.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`. . ------------------------------- ## Plugins 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-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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6025 Depends: libc6:armel (>= 2.31) Filename: ./0.7.0-rc/zenohd_0.7.0-rc_armel.deb Size: 1905136 MD5sum: 606ab2748d05ffa7c358eea6d812361c SHA1: 911e6a69a0e14c20ac9d9a8b249b1eb877272108 SHA256: 5ab3d318704697227d15fefa851641da12ea4275345e2ae93e3eb8dd6557a2fc SHA512: 2ae66cbbecfea0fd1a2788ad1ff45c7a78f3867eaf8c945a5a892817596012a2fcbd0fa6bf42585966195b72c47381338ea36067d843deab9311ce54d6155284 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 > /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.62.1), so no special configuration is required from your side. 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. . ------------------------------- ## Previous 0.5 API: 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. . ------------------------------- ## 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/*'` . . 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.: 0A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random UUIDv4 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 `libzplugin_.so` on Unix, `libzplugin_.dylib` on MacOS or `zplugin_.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`. . ------------------------------- ## Plugins 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-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.7.0-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5869 Depends: libc6:armhf (>= 2.31) Filename: ./0.7.0-rc/zenohd_0.7.0-rc_armhf.deb Size: 1904524 MD5sum: a0e528368776695a96ed8b2a9e36d2a1 SHA1: 21f9814bee8ea9a5fa0bd56e2b8b83dc398556aa SHA256: ccc8100112927ab3a5d732ca97c20fa8c262133fb0752bd3530bb15d9f1e328f SHA512: de7f7e513f8d37b128da07b599aa1955e452ae3899cab1b8342a8e9a1f01161f43a9b195c07fedc0dfbb54a6e24429f662f94691235a004f2363d49caebe19d4 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 > /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.62.1), so no special configuration is required from your side. 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. . ------------------------------- ## Previous 0.5 API: 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. . ------------------------------- ## 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/*'` . . 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.: 0A0B23...) that zenohd must use. **WARNING**: this identifier must be unique in the system! If not set, a random UUIDv4 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 `libzplugin_.so` on Unix, `libzplugin_.dylib` on MacOS or `zplugin_.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`. . ------------------------------- ## Plugins 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-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: libzenohc-dev Architecture: amd64 Version: 0.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 125 Depends: libzenohc (=0.7.0~dev) Filename: ./0.7.2-rc/libzenohc-dev_0.7.2-rc_amd64.deb Size: 26680 MD5sum: dc15a22cc6807d526bb9d8f5f0c99c5e SHA1: b64fa908e041d78a8a29418fea4c08d565833e1c SHA256: 099405dace93abc922e0fac117c36fbd42d4a6b10ad65bdb3be236ace853147e SHA512: 32b0a428931e90a58cf7a927c63d44e2d1bd6e63c6850ea47274c9a755a3a5894f3b0dcc0ec18f8cf469dfe06fce6fab26bf9e3b5b2c83e791f0f825e3646747 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. . 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 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 125 Depends: libzenohc (=0.7.0~dev) Filename: ./0.7.2-rc/libzenohc-dev_0.7.2-rc_arm64.deb Size: 26668 MD5sum: 44ce331079af54ee11eb8247f0106763 SHA1: 9ec2933d4394ba7ef397f55a2df516bd03d06ac0 SHA256: 7d3f95b0162fcdaf910b9980705a5bb269ad3e04faf18a1623f4c3a40fdbe1dd SHA512: 789c6782621c037964d1217a3b643d73748eacc1ee1cae7a696b7dee4628fa1ad97ec15d2e9cb1c6e38396744c2ff9793e6c3f302635b6b38be01b899cac370b 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. . 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 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 125 Depends: libzenohc (=0.7.0~dev) Filename: ./0.7.2-rc/libzenohc-dev_0.7.2-rc_armel.deb Size: 26668 MD5sum: c22dc2395a4ce6a9b5096ce50b070c66 SHA1: c20d2afc2f541f49984726a85fc69e9116eb6933 SHA256: 21f01a84c9f21e66054a56253cddaa0c510f4c667110a32d5f8ce65c5b0a49bf SHA512: 8575d7e61e1e2022ad079471d91f3718d9e10e65cc4842f14a478b09e522da182721cddf6578f8d64999eba42710525afe8af8c7c4e0bc9513eea924ea326573 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. . 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 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 125 Depends: libzenohc (=0.7.0~dev) Filename: ./0.7.2-rc/libzenohc-dev_0.7.2-rc_armhf.deb Size: 26680 MD5sum: b4ec56fe77bba0c05ed13bdf67d142cc SHA1: fcfb0afa7888b7bb23afd76bd6255fbf5c385690 SHA256: 4805aaa7cfd789624744a083ac09f80ff0e1e35ccf67371b164ff46eed0a1fe4 SHA512: 02b473e5630a82712240ac9694c67113d9e83c5414a8d94c16e5135f3d0f5b2f28305eea763f36fe9b3967528534bdf011936b878b392d56b365bfda7157ec87 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. . 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 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11765 Depends: libc6 (>= 2.28) Filename: ./0.7.2-rc/libzenohc_0.7.2-rc_amd64.deb Size: 3151416 MD5sum: 0984daa69a3f38f3ab10ccf2d64e1202 SHA1: 7b428027caa9bdc54c40c735fd82ad5340796fdd SHA256: d7d97d03a6e1b227f6f4c16d364c28e0eb45d305ab779c64f8b735a3f609ce90 SHA512: 13922f63e502c6c91db3e7c7e4b739d711d7ae2dfb03aed8ad2ec64c1c41fc46f75ac1910ee961a537a5c53e6e89e388576444c512022178d7028ef02286c894 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. . 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 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10507 Depends: libc6:arm64 (>= 2.31) Filename: ./0.7.2-rc/libzenohc_0.7.2-rc_arm64.deb Size: 2816216 MD5sum: d11b83fa536bad8a18ba469f8386f42b SHA1: 80e43e5cafed6bc74ca49513ab806b59b129dc0c SHA256: f749c6698cdb430c6c09cfe54063f2c4f46c3a4ded4db89069e77b001220114b SHA512: cc4304fccafe08450d4ac894e6134d344619708c827a4cfe5bbd4a5a61c22e7995fdadd44db28b88ea5105bc5454e939547a6f9717bfee4ac1836bac82c77d9d 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. . 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 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10775 Depends: libc6:armel (>= 2.31) Filename: ./0.7.2-rc/libzenohc_0.7.2-rc_armel.deb Size: 2923264 MD5sum: d6abccfdad6cbbe863f8961dd54bfce7 SHA1: 67ba2b1afb722ba181a064fd2499a3c70d4fdac0 SHA256: ae1637059dc3f95d0493d01ec80588393ee458745ed8ddee0b9320e3acce6400 SHA512: b4ee555dafbef07386d56dae9116c77545f166f4eb8dc97cad0524e4dd4dee467b75c19f65610d50c2cadc96efebc12ae4cc87542ab3c3e7f8221e1b2187e2e6 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. . 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 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10586 Depends: libc6:armhf (>= 2.31) Filename: ./0.7.2-rc/libzenohc_0.7.2-rc_armhf.deb Size: 2913164 MD5sum: bcbc4eda37351e07f1dfa1010f7c2c93 SHA1: 00cce64b75eb7120fb0615a5cc82b3ffb5839493 SHA256: baacd7f8a0d649fa0c20ed2e75b00db294016174ac1dc99b6b3e023903a9859d SHA512: 2f9abc4587db89ece3802748ad731363cd80733eb1ca3e64275d7ddb8b4534fd0ec38726e5cf882eb949f22b7addc4be06d3e79c08de527ebc7abf515588fde7 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. . 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 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_thgr ``` . ```bash $ ./target/release/examples/z_pub_thgr ``` . ## 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: libzenohpico-dev Architecture: amd64 Version: 0.7.20230606dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 380 Depends: libzenohpico (=0.7.20230606dev) Filename: ./0.7.2-rc/libzenohpico-dev_0.7.20230606dev_amd64.deb Size: 42088 MD5sum: 7cbadfd0402a341bdecbc2374c5bddfb SHA1: 31331c61bd7a36bac521de4ead07440218974d2e SHA256: c80eec21c0ed82bf28bb00ba1dd95f69c4f1163fc9ca4c44e2549c3605c83648 SHA512: 6540f248729e7be10d78226b0efcaab7751e1fcf3342baab6209f1fe3b39b7eb2041dbc969b94d52a8529bd322b96787e85e21dc543391acc1bdfad249af3707 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: arm Version: 0.7.20230606dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 380 Depends: libzenohpico (=0.7.20230606dev) Filename: ./0.7.2-rc/libzenohpico-dev_0.7.20230606dev_arm.deb Size: 42072 MD5sum: 7c1e011b5de400c7dd38966af2a0dd32 SHA1: a2233b3ac4198e67fdc428ca6d9c1d4f79c6b47a SHA256: 7533d21fdbcaf4211a3dabd10ef4d336ba1a7ffd4424de02547fcba4a79db0e9 SHA512: d7b8e716cd9d6f7b7b87215c90479f0af2eb05d9a37cca71a5e74fe2c18a32908438b3a66d109fe9d19698de5ecd094fe1f206cb572a672d7eed18cc4996018a Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: arm64 Version: 0.7.20230606dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 380 Depends: libzenohpico (=0.7.20230606dev) Filename: ./0.7.2-rc/libzenohpico-dev_0.7.20230606dev_arm64.deb Size: 42092 MD5sum: 5bc983cdfea83537f4c3c3fb2e7f10a2 SHA1: 4749f7b10a3f2e2d31b9e8a28498ec1840f71b5e SHA256: 63cd56d99ac0b070c7a75a7c08afa9338847210a86390a612a91e300699ce1b6 SHA512: df3d88b8974150ba8b9926641858190e10265430d4a63ae1d2c9b4f4ccb5532064593278eb5fb93a5f4f57f1db870b4dd9672368dd5da97503826c97a260ece1 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: armhf Version: 0.7.20230606dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 380 Depends: libzenohpico (=0.7.20230606dev) Filename: ./0.7.2-rc/libzenohpico-dev_0.7.20230606dev_armhf.deb Size: 42072 MD5sum: fcf8b0b4ba23076aaa588d5e0ee4be95 SHA1: 410ceca845e421dc0ef0cbc900371444eb5e1c3d SHA256: 801afb0fc5d0eeb5878a91f7a80914850487e7050319ebe12d51ed9c0fbde123 SHA512: d66e8e07e82a0ac9e880c3d13bc9dd0ca3a5ef9e235deec92912b1da3259a584bc1b9167ca1637fc2ace24155f37ee9f98bcd168145b978357d3e9c94aff3776 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: i386 Version: 0.7.20230606dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 380 Depends: libzenohpico (=0.7.20230606dev) Filename: ./0.7.2-rc/libzenohpico-dev_0.7.20230606dev_i386.deb Size: 42080 MD5sum: ad971af78950a8b67bb8fa68ad26569d SHA1: 93afd7b9b365e56123aad6effa0db4c6a3c026d3 SHA256: 9e01a9d0bd52562917474096bb94fee793d8b563f4d489938f6f9c1e76e00a83 SHA512: 0de7d511f98318db5911eff41b5f2acf923d35e41eb4c1170023f09313cfd0caa59776709eb0e1f620cc1e55ae933d16e23b40a8ac612010d13f7e2ed57385ee Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico-dev Architecture: mips Version: 0.7.20230606dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 380 Depends: libzenohpico (=0.7.20230606dev) Filename: ./0.7.2-rc/libzenohpico-dev_0.7.20230606dev_mips.deb Size: 42072 MD5sum: 0aedb3445cb8c8d1c8d7e5a77baccef6 SHA1: 6443e19a2f746886deb17afa9730b66a524dd237 SHA256: 7f341f4c219a01b0fabb045cc5d05d957df604760903b191c91505ecc9e643bf SHA512: 1ba5fc01d2951bcf82edbefe5046fc2767c406bcd38a53a72562da876127416ce94d4ce8574734541c58ea480a559d19cf3fbdb3fd09e0d43cd1a752f4c53c10 Description: The C client library for Eclipse zenoh targeting pico devices - devel files Package: libzenohpico Architecture: amd64 Version: 0.7.20230606dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 424 Depends: libc6 (>=2.12) Filename: ./0.7.2-rc/libzenohpico_0.7.20230606dev_amd64.deb Size: 72884 MD5sum: 899a42c7d38f26c2e8f4b800ca73ef2a SHA1: 93d0ae1e41e760cfb2c40838ad1fd4368bbacaae SHA256: 304eaed714f96f02deb9c17a3b6305fbd4a4cd3bc2581415cc4750e4b4743889 SHA512: f07557390dcfb80ded5992dc1a9efa78e370986fa56774f2c3bd0f0551599880da10f3500e82208fcdc557eb8f17b3aa1e8fe2a42f1797a6a8daec3c674ee3ee Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: arm Version: 0.7.20230606dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 267 Depends: libc6 (>=2.12) Filename: ./0.7.2-rc/libzenohpico_0.7.20230606dev_arm.deb Size: 52332 MD5sum: c84a85c8a64b5ade76cfeb84f740a6b1 SHA1: d0f9c6bbf29469708e27996cbecf49bb6ebc630c SHA256: 46bc311602d09d7179abe31958e0ddd5952a9e65b4ca99c155d7cfdfd5f197a0 SHA512: 03f59b37a7680ccb79a7cba92e4bfe37dc2867ee3966a59d804366bc8628e0a6ce0c5113efbfb6adf2abb82b3c4efefc5d0448e66b5eeeaee05e3422cc2b196c Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: arm64 Version: 0.7.20230606dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 417 Depends: libc6 (>=2.12) Filename: ./0.7.2-rc/libzenohpico_0.7.20230606dev_arm64.deb Size: 66752 MD5sum: 449ce2d89aeda0a2251edd977365eca8 SHA1: bb85d451b03bf131fcac9ddc62dd18860db5b6c4 SHA256: 8eb5ca1ecdf413ad87013d59a4a834707512e850c15431b9b2a8a3be01b620f2 SHA512: 1574a4cae8821a02579f062ce6f144fda563b0fa6afc764a1fb9f592cf21dedef0a46fe75c05c439d7ac48732780cb8650722f6542da49b978c4ce35e0bb0304 Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: armhf Version: 0.7.20230606dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 267 Depends: libc6 (>=2.12) Filename: ./0.7.2-rc/libzenohpico_0.7.20230606dev_armhf.deb Size: 52564 MD5sum: 5dc43bc456212539457b802440f65019 SHA1: accdf6369caab350b364fe43bff3539e29056b5b SHA256: 98cda78734f82318b4e07bb217656490eb429a4c2f2032f22cb3af870c45d43a SHA512: 1a9ca6f29e20a174a7e51ae1854b850f206be8cea45ed18d14658f992cfa3cefb5ad3d55ae856f32bde2c1e948da7886e5557a567af070089ce04a370c79ddf3 Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: i386 Version: 0.7.20230606dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 398 Depends: libc6 (>=2.12) Filename: ./0.7.2-rc/libzenohpico_0.7.20230606dev_i386.deb Size: 83808 MD5sum: 971184d1bb3154769b9ea6e2f0241238 SHA1: 27737e1e242a4849517650bcc9aa0d48fd822574 SHA256: b6e38de37053ddb050bc1ae2c2897a3a56ab24d8eed5863b68b4168bb7b6b1f3 SHA512: 4cc3dfad8d7e20ef02ff9a9edd1ab8e3fa98d6115a201c71c97a6a3031f8c5164ce79dff69b1535644710f49be62a1b7683dc678bd37eda3a741c43e7ab8c74b Description: The C client library for Eclipse zenoh targeting pico devices Package: libzenohpico Architecture: mips Version: 0.7.20230606dev Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 353 Depends: libc6 (>=2.12) Filename: ./0.7.2-rc/libzenohpico_0.7.20230606dev_mips.deb Size: 61672 MD5sum: 38f9f3abd1aed580d40b5b6be1337f27 SHA1: a9a6288b941379df042f7a0b66bf215c7b1634d9 SHA256: cdba744b1ce8409b7732fe70f1c2be6431b07c8e69319dcf6528a00f0b485da4 SHA512: df473e3c58504ab21e028695466dce15b7c1310721756aadfb39df3a1d2a2cee53ad0b2e9f2a6b5f0290e13aec68e3ff1f2cbeb7f658cbf45c62b292dbece7c9 Description: The C client library for Eclipse zenoh targeting pico devices Package: zenoh-backend-filesystem Architecture: amd64 Version: 0.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9542 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-filesystem_0.7.2-rc_amd64.deb Size: 2923076 MD5sum: 8bc530d7c51d8966d759f63272474a7c SHA1: ebb146e566932470794544819d749e23220d402c SHA256: 07b5964ef3adaff40170c1eee99bb806744933db3e042b3a6e9c06116f1841f7 SHA512: 960a03ea48665652cd74a60983aec00f700072e8562af6867bbfb65be4725ae63bf96cb56ac31b865aa57b2ff4a3b8362bd622c9bbf02457fbe79b2588548fb1 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 [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html) and [Clang](https://clang.llvm.org/). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8394 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-filesystem_0.7.2-rc_arm64.deb Size: 2538116 MD5sum: d38fe2cee469b811b980da43f4b46e95 SHA1: 11e2531a831d7538cec20465826fe90318967935 SHA256: 7d3e8846bb4d150bf234cead9d0d2e0b9a825e35c654fea13afbd4e473ce9206 SHA512: 8a376d3b00ea94d5ddbe431c6ba8e3a30a6d4fa781d09672900a1133211235605d677dda9c452aeb583a8682dd736df3d03e1fb66e0cf4989132a0c5f767e7fe 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 [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html) and [Clang](https://clang.llvm.org/). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7957 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-filesystem_0.7.2-rc_armel.deb Size: 2483564 MD5sum: a7812456ab6b1d422c0db9b858cabefb SHA1: ccdf4e8b144bdc3586fdeceeaaa5a3075a28bcb1 SHA256: a090f08b07d9f2fcbf1a7d55e2278977a5d54728234f0e7e3d7c8578516e7d43 SHA512: 8cf9e13d9b0fa4a02932497f8206457ea66b772520c0569d7e32722bff5df5c51c7124dac9265b48475873956d3093c315319b3b2d0b116eb17b2a3f2f011c9d 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 [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html) and [Clang](https://clang.llvm.org/). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6205 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-filesystem_0.7.2-rc_armhf.deb Size: 2585672 MD5sum: 1e212d9f380401d1bed2f4ed64e4f91d SHA1: 45c9a0cb89cb05a77d16b31abd7599033e71cd8c SHA256: 3f940d634bc9aa8cb6d8e85201b0f6058ec85b2d443531c79824487c750e0dee SHA512: 915884ce6130a73dbd8effb72226cacb3e7279b4fa0b585e2d41128e42a03d0781560a2e355acdbffe1a3f214cddcad718bfae08775ca521ac393b4ac96d209e 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 [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html) and [Clang](https://clang.llvm.org/). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4913 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-influxdb_0.7.2-rc_amd64.deb Size: 1543928 MD5sum: 64d681f05f7716ed9ecce3a4cdfd4baa SHA1: 2e26758816ed369e3e307bc3641ee44978480ad8 SHA256: 5239a263dbd70c9495fd63d4d88e7bee56a54bb8890c0a51bb5a24d59631a571 SHA512: 569a0f8dbb89f08a20dffe0fb5b344dc00e84dd476983b49ae911ea2df906ac7d06a690b1916f684dabe2cce3df303a19c282dc2f2a9bbd80eb34f079ab67a8f 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). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4417 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-influxdb_0.7.2-rc_arm64.deb Size: 1381488 MD5sum: 685a9d106459f5a02938befe38b0db47 SHA1: 538c21b018526465aa5be04fc550b06826e35220 SHA256: bc5170f8c194dd5eb6d20baad698aa140e230ef8f2933f2bbdab78189ba6d15e SHA512: 2e29c91cad3cd68ba632773540ddfd30c391361c3a084dd89d9be529ed76609829596905a6d626a4ffaa11372bdebcee5f1f552de303bb4b169d88bc81c3ec86 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). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3880 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-influxdb_0.7.2-rc_armel.deb Size: 1174892 MD5sum: 8d53678f3a67ab27424469af5ca499f6 SHA1: 9d978d4313667116c9b58f67a46e09df628c7795 SHA256: fcdb3238c2deab8564f3a18c899d521f9e63dc77c8b732a10f3ae4d99ceaf565 SHA512: 8ea99f7e6b8ef1a9a592f2462ecc0ca1ea7670daef6f5eda2e702758951594e813bae1ee96dc5c42dfbf7eb1f1561ce7eec2d51db1d5ec5743b9e398ea0cb6cd 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). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3796 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-influxdb_0.7.2-rc_armhf.deb Size: 1170584 MD5sum: b653095addbd72d371118fd542fe3028 SHA1: 33f39c819e2f42311414f43ceec53f68e56cb0b4 SHA256: f134c229b181dc969ac4658828e01f8829818af28a57ff1f4d98b408d062adfd SHA512: d2dfe83acf1fb7b677ac4a20c2224944a44e7e0cd08e7649929c57c3e3873b9b3e926b4b98d9bdef571a17a70a43a151c4a972911b61f1f01298ab9422cd48e6 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). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9433 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-rocksdb_0.7.2-rc_amd64.deb Size: 2899356 MD5sum: a13ea064e09d4da8f268e585cc68fce1 SHA1: bc986459c6c29a3572ce0256d3a5c339c4906ff6 SHA256: 130845499a2cd10125dca802b6984235e15bbe19571cdbf00e062b1f70e19e01 SHA512: 0ecfbd2434aef62c05a153505c17c9b4d26c494109db2f098c54ddb45acf6abe552d6471f79cec9cfa58d7d6f0bb0a11570ea82cdbc54e72e0e15c6169423fac 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 [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html) and [Clang](https://clang.llvm.org/). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8245 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-rocksdb_0.7.2-rc_arm64.deb Size: 2512020 MD5sum: ce13ce19e0f94996a944df3f97a061ae SHA1: 1388a11b4eadfd0306dd2b3d0fc601e37df2d1d0 SHA256: 6265d9986c95862a8fd7eb36fecc4caf1a0eca40e36dc56113b228b70763d668 SHA512: fdaffbb0102b26e210ad6b7d38c87367074cc2150e16d401cfee8ee4fca9b58bbca9d977ed2e390490456babb0dafbb9a4049fe0a592ae1f41d0d1a689fef110 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 [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html) and [Clang](https://clang.llvm.org/). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7912 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-rocksdb_0.7.2-rc_armel.deb Size: 2458788 MD5sum: 0744eb7f03dfd65e933110601ec823d0 SHA1: af9bf07b1a19ddf2a224c25fd0b7f050cc2c72b6 SHA256: 8deec3bb3b54090ca3cc7fb7282c6e6e69770c079e1a7af7cf46bed40071d8cf SHA512: cad28f65f9d165e10314beec996850f032b7cf711046fe1bbf68c9dc09a1db2d696b339bac9a967fc986e61f416901098b2d57d1fa6eaf73777c878a0ad00913 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 [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html) and [Clang](https://clang.llvm.org/). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6116 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-rocksdb_0.7.2-rc_armhf.deb Size: 2568796 MD5sum: 4ebc4bd9ee44051b4da0a300070eb6af SHA1: e704e9409a4355f4dcde0ce1c91a278698e03e8d SHA256: aa5cc393afea3cf6c6ce1b715497058b960fe2622186e6416b8b24982debcc3f SHA512: a0ad8e9c8cb84a51cc963b6a77b351fe09d5ada8ab1dd06cb9a52db6f9cdf2860247e53944092b7afff4e7ede0ea8da638fbf7ac782cd42dfaac1f424b7b8319 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 [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html) and [Clang](https://clang.llvm.org/). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11521 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-s3_0.7.2-rc_amd64.deb Size: 2894992 MD5sum: 9964a688f9778da9b54f31df48cb11ef SHA1: d97a8e2b35a3690df55f90971717cc291774f82e SHA256: a5dc06ee8847adae2c0e1f01b212b269d8d241a7c4e4f1ae809c55871d3f67e6 SHA512: fb5d38d8d5d6bc3dfa21501f86ae2c374b95eaf8ad4b5f2d5f6eb4055189f2b5ca401ced358e364747857a196abead0a89138bcf8850a7e8c49d95264f1fcbfc 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). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10297 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-s3_0.7.2-rc_arm64.deb Size: 2630816 MD5sum: eaa73f62d44ce38911fad7c6aac478d6 SHA1: ab7759d926e06c9c462328c0408da769c7410006 SHA256: 46b6f934041b42b2837a8f9dd74a78808c3c99cfc36a6caf1f3ca9a52f9bfd4f SHA512: bd2e3de0a71def0407f4d8b7ba306793cb9c674e94e183207034d3d0c191605c9ad491d36b5ba96bcfd9c25e7fb3c31eb366fc8d62d42d712af6e47a7599c8c7 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). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9234 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-s3_0.7.2-rc_armel.deb Size: 2295824 MD5sum: a6757c8220910b4f64a3dae755cc8f03 SHA1: 52af4faa9117f105e60a2a33682fee97c337c9d2 SHA256: 0842623f30c3280dc07a27085f11e704c462d9362ae61f63f693d8694f75ac3d SHA512: 9594c3efce28cee52d8193fbcffaf7701b013c9edb4829cb517caf768244aa42f48502f04a154b6258d232ff5e06210551df42ad9f8e5ad50c9ba4e5c9b6dfec 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). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9070 Depends: zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-backend-s3_0.7.2-rc_armhf.deb Size: 2299588 MD5sum: ea562335af1faf00490d368b230248d6 SHA1: 10b4b370fe0c99182c4fb88496563629af16891e SHA256: 6dbe281ad25db9fac0750fc60d44bd9addbb6321ae24f18a6c5718ef9ff7d85e SHA512: f4c9885a3eacbd226a68980a54145456179cb99080b5f25afb3ce79d6818a8bd1ceed3d4c51b74c988b00acb9c80d82bac9da6e854b55ade9cbd637eeca01c8f 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). . > :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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9806 Depends: libc6 (>= 2.29) Filename: ./0.7.2-rc/zenoh-bridge-dds_0.7.2-rc_amd64.deb Size: 3117836 MD5sum: 366eba74f6d950ef253c60ae73ae49b5 SHA1: b8d547328fc5fcfa16fd7d55e721e2c0b620a674 SHA256: dd9c830c980284737765b368b7411add45cf3d57a0c2f9ba016635e49f7880a3 SHA512: c5de03aab935d48f62288ede076aa01532a2f5fbd52e60033c2193e2506822b0ed6d95e0392fb8d94251ea11f6a2cb7af996418700ccc442b3872d465fb00ccd 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8569 Depends: libc6:arm64 (>= 2.31) Filename: ./0.7.2-rc/zenoh-bridge-dds_0.7.2-rc_arm64.deb Size: 2818956 MD5sum: c6b45d59a2f83acb48f453041a7a1721 SHA1: eee122768a34eb737f51c8b44cc4ae1e2bd078ab SHA256: 90b7f088b482e83caec9e9a8ff9ec761c2293f2ba17cf2b57b98a7a8798a3d7c SHA512: c61c24b540888289494182d833b6eb61f1378593a198dfcc82b55949898a56fa205e7812124668b486926a02b371c2bf1debc211cab6abb763b1cec70904206b 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8591 Depends: libc6:armel (>= 2.31) Filename: ./0.7.2-rc/zenoh-bridge-dds_0.7.2-rc_armel.deb Size: 2763840 MD5sum: f04342757da393c303c982aee696a3c4 SHA1: cab2fc4b95d4ebe01fbc9f259f6e0ac864a8c845 SHA256: e1ea01099c037356bf663f9e4095f0dd1047ac455deebe12443ecd0472f26450 SHA512: d04eb98fdd0f9d98f742ecde39de2e1fbce7b5142024f4979aff314fdf224479eb28a4258a467e734135f8df07767eada3a2b64ee5ad557400edeffed1f342bf 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8151 Depends: libc6:armhf (>= 2.31) Filename: ./0.7.2-rc/zenoh-bridge-dds_0.7.2-rc_armhf.deb Size: 2772860 MD5sum: f1f5c64aad44b631ce421ae166656504 SHA1: de91e2b84d3bfa1df0d165612b6ceba3e7e7b1a6 SHA256: 57f357323b67bcb143aa567e9a04a901381a435ba2ea9351a9701ca259989eff SHA512: 3486fc13c9d3136aaf7d9b698e714a248fadf9aa67570492746a22414e3f36c2533bd12a32bc2d8a879759936994b819a8c61587e687a691ef37c70222d978a6 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9052 Depends: libc6 (>= 2.29) Filename: ./0.7.2-rc/zenoh-bridge-mqtt_0.7.2-rc_amd64.deb Size: 2842856 MD5sum: fc2ad30ca977af77222dd66f81744693 SHA1: bec0d2e9759a1fde7b1992379a912a62c059c167 SHA256: 9f13c602f9600090db5d533af6bbe105cf9904f7b7530cafc094f09c89ba217d SHA512: 62d7a59b9e5f19d7d1171e68a84d5fe613c176dc20b4d913b4a81527dc6c42916721c74f0d78f4d76652bad3a5834e1500f349d08089a0278eff0960fad97533 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7836 Depends: libc6:arm64 (>= 2.31) Filename: ./0.7.2-rc/zenoh-bridge-mqtt_0.7.2-rc_arm64.deb Size: 2563844 MD5sum: 2cb80ea3c9a0f0f64a613b4df8f94e7c SHA1: 4b3b3a0db42805ccad51386c7f6fa894c0e368e8 SHA256: b48cf4f24298f435f6f8973256ab7e57d101a6fbaa8bc776ef17f22d4a410c42 SHA512: f4e94d2a788125ca9fa0e55f08216db9363e1033acf2edb4762b2fb73b334a59ddebfa9f2e0e468e1a89e34e0b66ea141ee4986f09c934ce0f65eb951f1e43a8 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10280 Depends: libc6 (>= 2.29) Filename: ./0.7.2-rc/zenoh-bridge-ros1_0.7.2-rc_amd64.deb Size: 3104324 MD5sum: d64ec6cdb48b6ed57b104670b5c11a33 SHA1: 991880d888bb768ece271e31c1bf17f723844c76 SHA256: 3305164fce8abd2767a10ea960647dfa0c3d36866cc31e3302c2914a06226158 SHA512: 846e3d786fb4d593e748f8175ecdc24b450f365db06636eeed990cb9ae2c682e7e81bb4746c800bd333e70a6fb4c7d412680188dc03b132a0b2459a1ca6cb1bf 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.7.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 110 Filename: ./0.7.2-rc/zenoh-cpp-0.7.2.1.deb Size: 15240 MD5sum: d6c01997320a695507bc036410ffd23e SHA1: 0600786e3aeddabe064c28da27e2f72e6f2b6db8 SHA256: 3ce50ffa85e41372814bd1d627271363d34b946df08b69069526f65f351ac8cc SHA512: ba87d0bee7415ccbef58d708e8b0b1d62b6e2fe0ac9e59ba5f0fe085ea3ebe66b7289a8c0efe9877e2c64fe2469bdd4456dee0f79eb6bea994ba92823884647c Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: zenoh-plugin-dds Architecture: amd64 Version: 0.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4022 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-dds_0.7.2-rc_amd64.deb Size: 1226128 MD5sum: eaa8ca73e78a48aa8038c040cb03d110 SHA1: 63ac598b53c4dd9ac51dd1adb6b32f7cd583e02e SHA256: d5a98fe2f1aa91d8a6dcd77136ca294001ca2d5854c1d1848111d627ad187e96 SHA512: 6d1c43dc34ba2f6640db6fed4380671f08cfb3a40377936fb51d34cd47bd0252855199c7071aff1df0918df82bd7ad610850376f42b917a1240ffa63deffcc89 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) - 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. . . ### 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. . ## 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. - **`-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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3594 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-dds_0.7.2-rc_arm64.deb Size: 1083120 MD5sum: 3bd38931c6a57c67fd7412c140ec85a8 SHA1: 7778d615d8890ab77cfe4fcd7733da2d380b9a67 SHA256: 7de55c9071ea13f655782814c88f11912c21bc3ced28e49196d3c3b05d93d98d SHA512: 6690de4ea3b05e82ad279594e284861903ce465c251d888d9d7131eb10fca823f4eb98067308ea92644b11430ce6b611ab3c020563c9ee8cc1736afee1f4bdc6 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) - 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. . . ### 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. . ## 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. - **`-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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3429 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-dds_0.7.2-rc_armel.deb Size: 1063248 MD5sum: 5bdcbbf092d53bf96348ae6bb70b8b27 SHA1: a16037515282466e6b7ed53fcefa1981d8d9acd2 SHA256: 1e463fc49e80555576d494c4758bd6c5fe8b55a6bc5f1919495f243c42e36322 SHA512: 80bd082cd63391d8402dc5d99e94ec61490bdeb1ddf56c4931e9a72d06dc7fe3f51ecb1598dfa122a3043dafba20a1c62ccc3536d0bc4f7b645ee20c4eb87e33 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) - 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. . . ### 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. . ## 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. - **`-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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3149 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-dds_0.7.2-rc_armhf.deb Size: 1069892 MD5sum: 5ef5d5167aabdef96aade74717382dd7 SHA1: ff4f2f043cdf8780115930aab22d34dafbecf8fe SHA256: aa2a5303bfed9df42a8f937a4e924dea61807347ee9b98abfa349a7dda633695 SHA512: de37dba297685ba8898d8175d0d78ddb018ed8bbf997e57f6f9b57265bc88bfe0b6bc00463a156fd0d4ed3641f2433d72b0277e939408aa34005638b0ea1a3df 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) - 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. . . ### 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. . ## 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. - **`-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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3282 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-mqtt_0.7.2-rc_amd64.deb Size: 937148 MD5sum: e1f4b5a4f49060673edc7ed5f3ff9144 SHA1: 79807efd95870b9d04e5911b6722ff4db1e78967 SHA256: 4ed63f18c97768758271f01eab25ef713dffebd76d2f63ea1575c379bdf20142 SHA512: 95e428edc9073b53301ab78f0ec136d04fca7a708e368cb2036a497853d384b0e290366edb16eb5ad03e366682e7c55192cd26daaa018cd525d3e7b45e1cfa71 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). . 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2882 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-mqtt_0.7.2-rc_arm64.deb Size: 814064 MD5sum: 6887d5c74c844193c6e13ef9b7e2271d SHA1: 6681bab873e1c9bfef3e11254627707875b8959c SHA256: 4c7590d91d98f78f3eda5a01fc7e2ac46c73ec193ca3e1515d06535ed90daa83 SHA512: 5a5c6f95536f763f4a405754024347c3ec235bab479c83f1d9877b8c36e5c7fab222c1b019f7b89f74c534aa1f0917648e6dfeae4f30f2e2d885719fac7c0da5 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). . 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3260 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-rest_0.7.2-rc_amd64.deb Size: 950368 MD5sum: 09f10056b438ba0bc824cd24cff4ea25 SHA1: ca09660c4ea4b3503da2c82cc1610268cdc0e350 SHA256: 2a7ee0f9059c8f317e73087dbc4a6d4d7482caa8208c7ad6be68fa1a8ed49fab SHA512: 15510bec41900c62a7b5fee620195932d2e6b3069c2e9db715ac55c5c3090b0755b69b5945ab08c457664b0253944ad585c4ce41881ff330eb34c2d4cd2c2b0a 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.65.0), so no special configuration is required from your side. 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2880 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-rest_0.7.2-rc_arm64.deb Size: 834612 MD5sum: 8290c0a506014b6d3961ce300c41891c SHA1: 34264e88137c197a991b020225354af3cda61860 SHA256: 1bd77ae53a347361e657e26c50220f903f2d9f64a16fbf8d88afd83cbc2d0544 SHA512: 908c6e6d8bc9e131dd814ba848775ba78c4411e990875e0f2f2c2a6b4215c89af4818393b0424493096ea49b719d107d8d9d45735265391252fbdc8e1e86eca5 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.65.0), so no special configuration is required from your side. 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2803 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-rest_0.7.2-rc_armel.deb Size: 841852 MD5sum: dcb0ed6711d73612b5fad93bc52c722a SHA1: c317c43988607f5a81231053c20c9af1b6d4fb14 SHA256: b99836e22ec917e1302697059cbc4e7ad6b64507850198f5fcc69c1c11ea6851 SHA512: a6d9ee83eabe23745cb65e6711983f772632d5b9d32b0d5ef2fc2f2cdf7cda96d447ede0240065999f34401534f6f6d4068227f73e8a7fc32913ce1ab086bacf 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.65.0), so no special configuration is required from your side. 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2747 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-rest_0.7.2-rc_armhf.deb Size: 832668 MD5sum: a4047b2aec4ee4a081de9a1ba8043a51 SHA1: ab09a8571eda201a5f86c302414df47488da5f1e SHA256: 778b11d6e95bf397ebaa2fb96d2aa0c891b91f1602934323138e574e7f5f81a8 SHA512: dc86d999135fb4a808641c85bcc44472e37d3bc0a7a71032a3ca036e1203d12a2c970cd35e1fd88ae8641cd3eb6075d3fa4ea6a4e232bb88d78cdee9914475e6 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.65.0), so no special configuration is required from your side. 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5582 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-ros1_0.7.2-rc_amd64.deb Size: 1681732 MD5sum: db8771e0c9040147700fa8ef4a91c2c9 SHA1: 74a3968db2bd8f17ce38b27ba1a6bc620a9e1770 SHA256: 7cdd80d6249d0128b11761904c1ee8f0983e64b4ed28d35e3cb1f3d6ecd4c826 SHA512: a98da7128c0652d0efdb7c4c284f492f8789ffb26de6340f0bca7114c4eaf576d8b9ea3486d291760ba1f67aa1e7571374dd73c99f3606f7fc3fcc06b7c25da6 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 . ## 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 Currently, only out-of-source build is supported. . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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) - 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. . . ## 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 -> ros_to_zenoh_bridge -> zenoh -> ros_to_zenoh_bridge -> ros1_subscriber | |___________________________| |______________________________| ``` . 1. Build everything: ```bash $ cargo build --release -p zenoh-bridge-ros1 $ cargo test --release --no-run ``` There are three executables we'll need: ``` target/release/zenoh-bridge-ros1 // bridge executable target/release/examples/ros1_standalone_sub // ros1 test subscriber target/release/examples/ros1_standalone_pub // ros1 test publisher ``` . 2. Start first bridge together with rosmaster_1: ```bash $ ./target/release/zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10000 ``` At this step we start ROS1 master together with bridge isolated on port 10000 . 3. Start second bridge together with rosmaster_2: ```bash $ ./target/release/zenoh-bridge-ros1 --with_rosmaster true --ros_master_uri http://localhost:10001 ``` At this step we start ROS1 master together with bridge isolated on port 10001 . 4. Start ros1_subscriber: ```bash $ ROS_MASTER_URI=http://localhost:10000 ./target/release/examples/ros1_standalone_sub ``` The subscriber will work with ROS1 isolated on port 10000 . 5. Start ros1_publisher: ```bash $ ROS_MASTER_URI=http://localhost:10001 ./target/release/examples/ros1_standalone_pub ``` The publisher will work with ROS1 isolated on port 10001 . 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 targeting to re-engineer rosrust to overcome this . ## Limitations - all topic names are bridged as-is - all topic datatypes and md5 sums are bridged as "*" wildcard and may not work with some ROS1 client implementations - 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3288 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-storage-manager_0.7.2-rc_amd64.deb Size: 951516 MD5sum: 39bebb4d0b8b3afa25a60d86d79fc021 SHA1: def3d958f9d8a4325e748591baf9b5768b532840 SHA256: b6b5c21c9fefac61a3bcd421bff29a59a174cb9c357397f3bdda73fb0bd4706e SHA512: f3ce6ccfc850f468f659712b566cd24b62014eae10149986ec75c9e5529846f9a5320e79763a3515d6f6ed7c4035fd798e03283968a78f720f7d23a305e4d9fa 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.65.0), so no special configuration is required from your side. 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2872 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-storage-manager_0.7.2-rc_arm64.deb Size: 826388 MD5sum: 0e2583b6dedb6cdbc2e217a9bff7a630 SHA1: e39350d06bdc19d7d586f726310a95ce20d90a8f SHA256: 39f615eef8f2f68f739fa79ace3888cbe6446f28e5f9b1f1b760fad6bde28316 SHA512: 5fdb66d503721a5f4b78796e430a9161727d41a9e33cac4642bdd00b5fe5e19c995a5db3a7b5e8e2a826938dbd1391d79fb0589008dfc0dd2ab522eb5adba346 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.65.0), so no special configuration is required from your side. 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2819 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-storage-manager_0.7.2-rc_armel.deb Size: 848140 MD5sum: b25c77d624ae1ab9d985b9ca3a095f75 SHA1: 1cf73af80f346f38c573e8d130c7c00549027004 SHA256: 0abf42cf9ff985e98dad7dee1572b1845d57126b53385b97f5334ff1d9b011ed SHA512: 62e20211a728d19a5d33c4551fd4f05b8c81271ddceadb453d2dd6a904647b901561905b02d72ee35f5714fa37bd2a897b2c6547701fade3d9e1420d69cd69f0 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.65.0), so no special configuration is required from your side. 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 2755 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-storage-manager_0.7.2-rc_armhf.deb Size: 835852 MD5sum: fc52e673f814418e52befe6b89d55a37 SHA1: 9aa97c3c118265d5750fc0c6e273618dd7e5aa94 SHA256: f3e552bbcde470d8ec22a1e3f87dc3557141453d595a40fc6496273152999ccb SHA512: 60878de1017c4f95784802010cdbecca7bc764a32daea37016ffc14118c747e52561bd323e762839710bfb4a576f5380590eec20c3abba1726336e6e31539247 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.65.0), so no special configuration is required from your side. 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4311 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-webserver_0.7.2-rc_amd64.deb Size: 1201584 MD5sum: 1ac64b9edc6dad13f93f1f8bd9a0eace SHA1: 22024caaf9598b860a4213d76970bef31cb2ec69 SHA256: 0b4385719931f3a0ce20be67eb39a3e908c663db668f6fd1b270b8b466af7b41 SHA512: 2596ec9db93d0e52537b9dba56960de16dfdcdc35154484e7ae3a164bca769dc6f72283d90ed5f6a2c9374045ae89ce3c3db3425314c582a68421fb9c17f69d1 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). . 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4007 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-webserver_0.7.2-rc_arm64.deb Size: 1072876 MD5sum: 18aa16a17db51e7d644f8f545089a470 SHA1: 23d16764536f04254b32ca00a63d5a7ca414020c SHA256: 62acfee0e769986a6edb746a08f67b54c008c6377b2001e683d5238a2112e5e7 SHA512: ec1900620c2310489896d7e25ba02d837a0e4e82e596736ab3ddf83dbed980057d38303f5794abdc2155ed09855275a4f9e321f6365f88a44d4a9a6544c834b4 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). . 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3682 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-webserver_0.7.2-rc_armel.deb Size: 1022668 MD5sum: 54d8682acd725900f3597c439025bc73 SHA1: 5e9f50fa8bb521b67e8fcc024fd3ee1fb79e9d6e SHA256: 1c5485a0c92e3b62ffc457ca9924bdce92ff44fb44ab474bc504ab14980fcc18 SHA512: 6390b2e81f0ebbff556d6e43cded858aaa9d74da8642ddd3c2ddba51b1a88082afee0b01bbd38c5f56b7c81238da877b0874c9d189fde501f72da6496945344e 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). . 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 3586 Depends: zenohd (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh-plugin-webserver_0.7.2-rc_armhf.deb Size: 1011780 MD5sum: c60f547015c3f0d740d757dc28451dda SHA1: a2aff6f4727a439886585e7a2cb02e67b06380c1 SHA256: 26bf91b0cd099b5972241a71739e0d4c345dae11611e28ad90a430e7a328e659 SHA512: c65b0f80330ce0c7d2d8817c8a02ad0aef8ab753845b3478c2d43a55e4afa45b2d95e45479e294eda3a04e3d62c8f6c05ed8d88ab3c8b8572d6e81eaaadaa451 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). . 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.7.2-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.7.2-rc), zenoh-plugin-rest (=0.7.2-rc), zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh_0.7.2-rc_amd64.deb Size: 832 MD5sum: 44b1658a1493a977af84fbf60fd981c7 SHA1: e8b88b6b4ec1c667665e62ceabe0256623bcb865 SHA256: 83f2e40b454aa3140a0bd2df13d64cbcbdfaaff69425f72bec6beba26b7685fe SHA512: 721453962d1e4e0a280639b290239eb1e77b11a931334dabdd65e8d360c10df1ad921b5a351bd35233d33b9b9a6c37aae4f532370e2bb9cc8b261446b217ddc1 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.7.2-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.7.2-rc), zenoh-plugin-rest (=0.7.2-rc), zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh_0.7.2-rc_arm64.deb Size: 832 MD5sum: bb6143c728168dc97f96c2d78490e52f SHA1: fb0231ac32796da3b1fa91e7c3220bf0c0f8d608 SHA256: 13db8d1a92604a87b715a4741aa7100d846ea9dd8aeb00f64c114a2fba1e47bf SHA512: d09050ffac5db88fffa19cf708c2d6d02381af1a5ce621b55f602daa0ef6aa288c2988636e640ef64bea2754c98266793cda742c842d8201db5aca6e0984ee46 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.7.2-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.7.2-rc), zenoh-plugin-rest (=0.7.2-rc), zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh_0.7.2-rc_armel.deb Size: 832 MD5sum: 254a2a4118d20276e575e19f02ed4342 SHA1: 345cdc840e0bc11cab8e4cd9ec957038572ff734 SHA256: 8e6cd9e303c92b2f23d3d0b1c5d9dcd5d771ab9699fadf88208f3053a06e453d SHA512: 409d4b002281d1bab6f4c200cc43e4b25e059b12a33d5d335329248a8d9ac6e2581e15133bccefc9a0e3b28d28437e3d0de17c5aee24e865d75c49bb60f90a2e 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.7.2-rc Priority: optional Essential: no Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 1024 Depends: zenohd (=0.7.2-rc), zenoh-plugin-rest (=0.7.2-rc), zenoh-plugin-storage-manager (=0.7.2-rc) Filename: ./0.7.2-rc/zenoh_0.7.2-rc_armhf.deb Size: 832 MD5sum: 2c9045ca19ca1876c4070c988a88172d SHA1: f03002fa62da6f3c5777d92f1a5e70736b50f1c6 SHA256: 3e6c216556d380764b71481167bdec04c45081149149ccb49b7d80723f38376a SHA512: a971ec1b7e8b85a682705ce1fd9d0161f40e73349b5f1d9db45228b5c05d707e7229d01b082f003ce64c31492d6e789fafbb11ec0e83a8f527a7c546857ac28e 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8080 Depends: libc6 (>= 2.28) Filename: ./0.7.2-rc/zenohd_0.7.2-rc_amd64.deb Size: 2508556 MD5sum: 978285eed621991b075bffcf4c92f68a SHA1: b89b7890118386625200b784dcec32ad251dd83c SHA256: b41501f2e12d5af622b04b6c5b26228f36c22d5e9e6b35595039fa1a76686e9b SHA512: 548471b7dddfe3fd8f6229a23ae14884d0540512ffa12d685eb0fdec2e9b190dcd90559ae155f17d03fe771942b5d70afad281fd14e7d1252ffc556f41669483 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.65.0), so no special configuration is required from your side. 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6904 Depends: libc6:arm64 (>= 2.31) Filename: ./0.7.2-rc/zenohd_0.7.2-rc_arm64.deb Size: 2251464 MD5sum: 53b2942a0a90c118c4271047456fd095 SHA1: 417b2a3f72e22794f19705a30693779514a4c2c3 SHA256: 1cf737879df5288570603090d821c5d1bb1ce753fd71d882eff42acbb5edbaa5 SHA512: a8e1650d98a75e98e671b83bd7c2866d69eea999921e1e1d9aea4a6b888fdaf69cc75d77a11c0941313a0973cc5dff9e4b6814ac8cebe216b5f90a43b48667e4 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.65.0), so no special configuration is required from your side. 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7010 Depends: libc6:armel (>= 2.31) Filename: ./0.7.2-rc/zenohd_0.7.2-rc_armel.deb Size: 2219552 MD5sum: c15d79676de3b9d2536d40066ce46610 SHA1: 6f75d4bed797710620bebe4470bad8f3a45329e4 SHA256: e63194554b168a7e0958619e3b47b4221ee80148bd992069003d143a6388e324 SHA512: db16229413bf3c5c9de85fdacb35f0df32b701cca090df6370fea26bfcec10a78ad4eb96d730b2460aeb8a02fd819aa28dbc96189cc8ab1afe7bbc5ab2b9a331 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.65.0), so no special configuration is required from your side. 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.7.2-rc Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6814 Depends: libc6:armhf (>= 2.31) Filename: ./0.7.2-rc/zenohd_0.7.2-rc_armhf.deb Size: 2212540 MD5sum: e2116545a037c3dd2043426ea3f88cc6 SHA1: 5428cb27f06ea334173c7880f4c772ad3f9b4268 SHA256: fe84aabef472f7ad59c20e24d2e78ef70d3883669e5d4116d2be5bd82dff2c1e SHA512: 215d5108534ccc062c8676a39ef2131fccad1da60c921252a47e8eac29619d2180793f51994a4f4082d3a85827210a9db759901c776241f49dfda4809cca7344 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.65.0), so no special configuration is required from your side. 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: amd64 Version: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11596 Depends: zenohd (=1.0.0~alpha.1-1) Filename: ./1.0.0-alpha.1/zenoh-plugin-rest_1.0.0~alpha.1-1_amd64.deb Size: 2207132 MD5sum: 2f361a49e4d4c5079d454a3833e93d8d SHA1: 9d92df08f5492a6ec0586a474b9168324444b64e SHA256: 95e2a268bcd3642130ef1172808899c4d94f56a72ceda07e9c8cf35004b85172 SHA512: 3bbfe86738d6bbc43031a3b2a0dd611d2dfe82a68dab4435bc1234683a5c32c12a33a46fe95eb8f78b19a87ac18b85d9e48038ebbb9d3c3149f618bf7a017f31 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10398 Depends: zenohd (=1.0.0~alpha.1-1) Filename: ./1.0.0-alpha.1/zenoh-plugin-rest_1.0.0~alpha.1-1_arm64.deb Size: 2000872 MD5sum: 143f021d0a0273eb62069ae11f342dd5 SHA1: 112af4f23f8fedff496756e78883a277fb2849da SHA256: 085c1818853417256a79ad312223837eb801ff268197401d2501dfcd87bb1290 SHA512: 33c93f1a614b0959b61f1f5cfb784a8a364435eba45918b7e67ccbab7835e3e822312011245dce0379818e722f55f6211533420716f1216a562d90ce848bfbb8 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8576 Depends: zenohd (=1.0.0~alpha.1-1) Filename: ./1.0.0-alpha.1/zenoh-plugin-rest_1.0.0~alpha.1-1_armel.deb Size: 1875688 MD5sum: d1fc11118d65cb870d0b27cabf640159 SHA1: 70c22dc887ec214a841bc18a6c6641af961b58c6 SHA256: 1f5de4b5bed728e24e7e58607bb683be05bc93b2b443057a4abd5cffdfd45014 SHA512: 8882da7effffdcee73725a581aa79f3886e3a9a21039408b6d1d0ede00640c64d4e51615b7b8d46ff8707e98ecb78fcf2b1c8c9cdf726e8ff13a74e47f56f73d 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8455 Depends: zenohd (=1.0.0~alpha.1-1) Filename: ./1.0.0-alpha.1/zenoh-plugin-rest_1.0.0~alpha.1-1_armhf.deb Size: 1864180 MD5sum: dea9e078042875afd3fe504d454969d7 SHA1: d97bc9fd30cc0c87cb34c56b4895501d45988359 SHA256: 138446169cdba1200ac5a24d74a2e4caae98d2ceaab102cb6bd042fc5feaa7e9 SHA512: 6973c4e244d62c7c93394ac34965eccb1bd0caa3ca1a948912fcea518b541509e12008f707e9950f582c5274d50052fb5f20b0c344b539e5839d30da91344ef8 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11954 Depends: zenohd (=1.0.0~alpha.1-1) Filename: ./1.0.0-alpha.1/zenoh-plugin-storage-manager_1.0.0~alpha.1-1_amd64.deb Size: 2279948 MD5sum: 4cfe4886bfa111f35a911abfc1024a83 SHA1: 66bf33b197c13aced38de88246cb29f6f0885792 SHA256: cfb9c8eb1cb93db3b2eb2a3720aa6bb37709f62c888ea3daee57774aa6ebf172 SHA512: c5b03bf699d8e9db43e04a2bd452d68ab5cf76ff2fa5cc67dd0a01d8c11a48857c5f9b443339afb29796b179c2ca70d29526cce701e1caff15c88e3e39c67bc8 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10710 Depends: zenohd (=1.0.0~alpha.1-1) Filename: ./1.0.0-alpha.1/zenoh-plugin-storage-manager_1.0.0~alpha.1-1_arm64.deb Size: 2064280 MD5sum: 56dbdcc33f4800540ce9bae4195e8162 SHA1: 2e3aaef429da269da746dc2d706da5288fad893d SHA256: 457db9276033952da5ba8d862c1d92ef64ee857055cb8b7fd8d0ad0d42ece71f SHA512: 1dba36e99e69ec1f87b1dee07b751d74d25778b60f45610d3eb73d5a214264c4c6f501a3e783370683a95829278d206eb198799d25691b420e899b62d01a9293 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8958 Depends: zenohd (=1.0.0~alpha.1-1) Filename: ./1.0.0-alpha.1/zenoh-plugin-storage-manager_1.0.0~alpha.1-1_armel.deb Size: 1962484 MD5sum: 1c6cfb99d3ad08ce49f020ba9631ce58 SHA1: ac1fafb3cda0d1b4e12359471f7b93e273cc15a7 SHA256: ced71fc79770a1c3c031b3990b87405f51351c9c62b668b9269b39a6524bfc48 SHA512: 5557e775acd1db957b36d78e38965c2297b4d4ae95614fe40e29bd76661b0bd11bc2bf25a5021bfc5b63080fc329d08b150bcc4563283370c15292a2d55a8aec 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8829 Depends: zenohd (=1.0.0~alpha.1-1) Filename: ./1.0.0-alpha.1/zenoh-plugin-storage-manager_1.0.0~alpha.1-1_armhf.deb Size: 1950980 MD5sum: 123e1a7707c4511df2144c0c889ef544 SHA1: 12ae2abc003d99fded1204a5b5bc272ef36a9abb SHA256: 63253b9d7569bbcd9167d1f7a96895658d233dd3b65854ee623a2cd11d71ad83 SHA512: 0670238f243f6e466009534d5c1cfb762b5f100a0cf2d99a74e2b191e50b9158dca6824449971d42814d697948ea7cc8c99962688e482ac1686281e65e4bb590 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.0~alpha.1-1), zenoh-plugin-storage-manager (=1.0.0~alpha.1-1), zenohd (=1.0.0~alpha.1-1) Filename: ./1.0.0-alpha.1/zenoh_1.0.0~alpha.1-1_amd64.deb Size: 17504 MD5sum: 613253f030f22015486c912417a15aff SHA1: e19a431c4d8538a84f1c6a7ea680320ebd91ea4d SHA256: 59ca8623c57b2a222c238475e62f4af931563c4ddd2ae73e97ed348609bffd0e SHA512: 611099fa8f16e2fc6db9896253b60b8311b3883d4fd0d3858ad6dd27e1f787972bc451d8f326cf868f7ce8db90f8c4bb11c6b314055dd9565935b79af0311668 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.0~alpha.1-1), zenoh-plugin-storage-manager (=1.0.0~alpha.1-1), zenohd (=1.0.0~alpha.1-1) Filename: ./1.0.0-alpha.1/zenoh_1.0.0~alpha.1-1_arm64.deb Size: 17504 MD5sum: 8e3eeb809497e0e206e33feaae845537 SHA1: 8940562956c677814d5fab9c716b850c29f161ad SHA256: e1d162fb983e79e86bf26077aa9c0db6f2c53322033357d860c5c7678253f79a SHA512: 4af73a88b11055f191271a182b342e3cdebdea12a361d7e813f63ace01ba836a358a92464b1daf1fa73546c9ef70f7afc4e66b1f793aec0ca593bf2e530fc3e5 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~alpha.1-1), zenoh-plugin-storage-manager (=1.0.0~alpha.1-1), zenoh-plugin-rest (=1.0.0~alpha.1-1) Filename: ./1.0.0-alpha.1/zenoh_1.0.0~alpha.1-1_armel.deb Size: 17508 MD5sum: 03394ecb1addba63990585b5819aed84 SHA1: cbff6aa08fc9afa84748474650a68af7dbabfdcb SHA256: 2259b0081fc48f39eda1616e8462554551b7a6cf7efa932661d274b70469d517 SHA512: 2e469dcfbdb5368c31e31aee810728db838e4581a355fefa07e6c459498de928fd75bf3367d329275c7707edc7f46e34e12e63317f0f327b01eac2e449e4c9e3 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.1-1), zenohd (=1.0.0~alpha.1-1), zenoh-plugin-rest (=1.0.0~alpha.1-1) Filename: ./1.0.0-alpha.1/zenoh_1.0.0~alpha.1-1_armhf.deb Size: 17508 MD5sum: 2132eea152136dacb3cc525794e202ff SHA1: 87d941478d9f52199cfda356cd49241b64d42687 SHA256: d6542d7a1675ab3a744ac5b1f249c3aec370551285a6cdb3e92b28c20335b6c8 SHA512: c4cc1861d4520b16c46b412dacddca8240a7cfd4a6cd333f77594d227a4aa919ee3cad2876567fbbc18d0699de2efbfbd9e84c018e0c819f399ab80df08929d6 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18298 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.1/zenohd_1.0.0~alpha.1-1_amd64.deb Size: 4471768 MD5sum: 500c6967630baeec01fbacbd5d004908 SHA1: 84942d7bbde58f2895aedcbc6f3df53563674481 SHA256: e50ca647fedf018a04b4a2fa6e35f0bf95f1ae8b6434a4ec1326e6212ca7a4b6 SHA512: 72560f2d0de39a831df396b6766c79d83d8aa44a7164ce01c64a16a700da546461ad465cc08b1e8d0665868fd88533997e9dfbcb1630434c244e95d86639290c 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16251 Filename: ./1.0.0-alpha.1/zenohd_1.0.0~alpha.1-1_arm64.deb Size: 4006984 MD5sum: 2db25bb2ae5a52a68aa547d34ccd99e1 SHA1: c566f1672c2156bfe756946bc63ffc43f4d9ae02 SHA256: 2cb4235923bb0c08000491e14e1fabe8caf8ca89d294d98d94787b31d65635c6 SHA512: 68ac39939df665095a8c9df6714e69071212b098437a0dc3c7590bbacb57a11bc00b071b975de22ce55215c41e26c7175b80182bd31a76c2990fdf6df991bd85 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17676 Filename: ./1.0.0-alpha.1/zenohd_1.0.0~alpha.1-1_armel.deb Size: 4353260 MD5sum: c8defa035b849baf27062aa897838603 SHA1: 28da2fbed95ea7e436f5c31130a32eb5a9a7f173 SHA256: c4dffed6f93978ebb18a6f15365ec2bf80d9920b76d835e78bc223f9dfcaabf3 SHA512: bfd34b3d94befaa970291de346022855b141c0307e8af70bf192d97fe1403b553715877f19df9e6fc3b468b3dcf2669bbe13e5335f9f356203ad139d37c23edb 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17447 Filename: ./1.0.0-alpha.1/zenohd_1.0.0~alpha.1-1_armhf.deb Size: 4395940 MD5sum: 66ede2ea996464dab333710b70e3af7f SHA1: 38d40ea6106289c92cace0d0dde61cdc1ff00700 SHA256: a13339bdb94232aca71dd7b1c58b10ae16d29adec1f02826f480e47725218cd3 SHA512: fb7f47399bfcf5f95579d333a7fec7c4450e826d2fcfaeb02d7a5fa6c54c190faccf03453b90270e98092bdb105629eea6e9e02e86a09348aca36e38feb82d77 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21206 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-filesystem_1.0.0~alpha.2-1_amd64.deb Size: 4695096 MD5sum: 81f1cd5263385cafbe3d10d5897918ea SHA1: 1b93b8527669f4b56d97dadd7094b7e010ccec40 SHA256: 5674c9c97a7b3a08cc446fa3c32ea168d326b1015d5c4be4c0687e88f393aff8 SHA512: b84412d4b826c1b5402be3837072b7b4b1171c667da600207899294a7e0fa33c3ce9a985c208c4fe5b14b84bcb79983903dba672633ceaf63f63c9788e5803ad 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19354 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-filesystem_1.0.0~alpha.2-1_arm64.deb Size: 4231444 MD5sum: f501148c0347118d9cb7f91678103e3c SHA1: eaa7180966c7a48625c041f6c4d292362ca932fe SHA256: b548e209dfe19348d08f6b7172a295af4e684bef506b73b3f66816be6b27da1e SHA512: 1140315241c2af63ba875cb940e9c4e12c29a63e7d063ceb3d2ca7cea4682923d6d479cfd031ea0e5dcffcab28e7c1de617c440f069b034f1714aa27f40e2954 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16882 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-filesystem_1.0.0~alpha.2-1_armel.deb Size: 4001788 MD5sum: b46f3254374683def8d29974518b3ca9 SHA1: 6b3e515bc61877a554ef9c0a83295e55cdb0e464 SHA256: d2fadd5355b3dba3edcd6bb3e0cf8b8c68d1f2915fa0770461fb7c0b08f74608 SHA512: 4feff3f65b4971f7ab6aeb7d119a320c4b155ae661fd48253a2c9f511c54a0d4fc01acf362464fa95a61ce58b503bb1dde1a3218abe3fe31cf98b3177dc24006 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14992 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-filesystem_1.0.0~alpha.2-1_armhf.deb Size: 4097980 MD5sum: 1d4114c5e42779e860dcaa56a0fb6a3c SHA1: fe703a2424cba8fb83bcb38e83da8e9910535780 SHA256: 3c205a32feb0777555aadd16dfbe4007099c53407748fc2fcfe276719124c4a3 SHA512: 7ebf3777a8c59fea4f3646b600a1b2829848fca0fbedbd44fc2fabfef9eed92eb1d66c652550df672b2da15dd429af20f34f0bf2287f3d5d7e7f35ec4e59759b 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16044 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-influxdb-v1_1.0.0~alpha.2-1_amd64.deb Size: 3196528 MD5sum: d2fea53ce0f085c98e9890868ac28eab SHA1: 86f3a62753a2764a2d85971b226c9cf581c83d29 SHA256: 172196350f912f7f16ec472aea4e490d40d2a54be2f9c6980d397ba62ecf23b5 SHA512: 2072c980e4d29f1f9f3ba66675b806f600ee5091ffd00271fe272cc3281f61d34793bc0565ac99f9fd4357a6a15957fee30981d3a83ee65e3257f69b04c84941 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14424 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-influxdb-v1_1.0.0~alpha.2-1_arm64.deb Size: 2886824 MD5sum: d0f543962783c1e21bcc3f5417f5e676 SHA1: af3ddce061a480bbec1bd652bc7ab40148496c2d SHA256: c18ba212a43e6193df0eceb6ee80f74c94be3f8cd55e851c5c3e6832cba2a098 SHA512: 7916a58fed22c7921973edb1c2adb6f8a194a59b290d7158fb70888916080f03cdda8037e6203bce316b758e2a169469b976c2e1bd48b30cf3b7b5db5bf8edae 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12185 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-influxdb-v1_1.0.0~alpha.2-1_armel.deb Size: 2624124 MD5sum: 507bfa1e87f7585bac047b64c7607a73 SHA1: c69c0efcc4620644f31e7bb0919539d2975405d8 SHA256: 4ba6a3aa6dc28a38f657900675c5db0ab866b65a40e650c522b858a6deabb6b4 SHA512: 5de8d469a1e519d46834b87e27e381cd6ae60e3fa4ed6fe52794889db50a4794d8c727b6c608414751afc1abc40cad8340e3c0f8751c005ff608a563fe4700dc 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12048 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-influxdb-v1_1.0.0~alpha.2-1_armhf.deb Size: 2613720 MD5sum: 1239a58668b901be953c42e54d99bc92 SHA1: 403f538dbfb4aa8ef49f2f9417db4c518e2936c6 SHA256: 339e97fca059d9416dcf617b62cfefc84e131bbcea0ecfd16ccea586f5e118c7 SHA512: dae4e4f85724219eff77296b376d1e517af291ba8524ec397759dc08a05be053fac78cf0388752b2ca2c8c2f55f02c7c1437d2b3472f3d4d4f4dd86f480169a0 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17801 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-influxdb-v2_1.0.0~alpha.2-1_amd64.deb Size: 3911588 MD5sum: 01092caaabc36015593dbac5b8455c1f SHA1: bfbedafc52c24dc5f0719d5980819404865e2fc0 SHA256: 77904554cd161fd2a47ca8b519049fdb4b2d82ab842191391a5b3225e1419c71 SHA512: 103fbb35b30b58e6514dec0fb2a6c2bf31c6617e90c9145d65a52a44dee6160459a5792c02f07806a7a45aee0ccfd33daf23bd7af550580bd39ed71c166df514 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16810 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-influxdb-v2_1.0.0~alpha.2-1_arm64.deb Size: 3597984 MD5sum: 973bc554a81c8e07e93f784ef5661550 SHA1: fc30e56dca9a291f1b42078a822f22cc64f53c3f SHA256: ce91fbfd1f2481316dcaf2f6c3c05359f95afb2f42c4e44c151c6a1af999bf2f SHA512: 23ebada14fe1b15fdea50e320da489dd6f00c077d3c86161d6b21f6a1ae6f3abf3d09e18f8e1d43d9d631f50afdbfaf413576006d707e22b5d5efbe4d56dcaa0 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16073 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-influxdb-v2_1.0.0~alpha.2-1_armel.deb Size: 3570508 MD5sum: d771156fa05434bc77f07f446bc4ac04 SHA1: 7980a6989cccf483addf3ade726666ba371d6345 SHA256: 8172c590fef93181294d2daf49bc49498d3e5ea07a16351d296c10334919f0e1 SHA512: 60815ff326acd6d44e4dfd12df3b959bd7265f43ad856311d4e167536ed6349048635ef3e8bf2af836a19c88be95cbc04c6bebacfaacdb00b79cc0f5612b8dee 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15955 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-influxdb-v2_1.0.0~alpha.2-1_armhf.deb Size: 3611864 MD5sum: 101bb1b83d960b28fd8f325c44adf1ef SHA1: 3ad053e05ae5386d9fa24caa994db93378b85f39 SHA256: 3da960558107100ff57f000fc44bc29196db901c0c06adb8da1a24dfeae59db9 SHA512: 43c03bae13692a37f3a136d23e201b412f054987749629f51a4ed924b41216a2535460ad370dad6aa019ac22a06d014f848e64f7985a81e99480381d8089d31e 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20845 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-rocksdb_1.0.0~alpha.2-1_amd64.deb Size: 4648596 MD5sum: 27a713a1f0d08c73e30ea73d0140a680 SHA1: 1de49d925a4f5493143bc0bf8a5f13498235e140 SHA256: c2aca650f38624e06c6aad6242a2daccde23c355cb5eecf36c6ed8b376cca295 SHA512: aa583752d1efa9ca5fcae443cdb499fd2cc4d59615b68e612f21799279699a649feb45c16243fd0356072e1303227793aba95abb6ab7f8e84e159899f2495657 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18846 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-rocksdb_1.0.0~alpha.2-1_arm64.deb Size: 4170868 MD5sum: 50dd30c6af413a4800ee27bd4680dde2 SHA1: 8a7316bc8ee1b4a7c827ccc659216e9aa8b13e68 SHA256: fd96bddbf1639f193af273c717eff2bbf5483d120dbe48b7a883d80af85e9fa1 SHA512: b91994f5d80db344da47c84270145c3285a9ea9975c95830c40975ac1d6bc1ec98b0a5860c20b43175e2e9f053782d5df6055e948c154743188c6cf62ed5ce01 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16550 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-rocksdb_1.0.0~alpha.2-1_armel.deb Size: 3955480 MD5sum: 50512074190bfe16d341ffe798c43ac1 SHA1: ad1e8e1d993c93b3f5e60d138520d30f8cfaf460 SHA256: 9b2418111e686ac21001872e08aab18eb8fbe3bc2d3b12aee858303e9a5e4828 SHA512: 6b667ca21d38a932b55433fe580a05f7f5a421d57bd15e0c704a2f1abcf6b26b75347d99f31b575348bafbe4a47db465dade7ce2a69859201fd889a2da6c62fa 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14617 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-rocksdb_1.0.0~alpha.2-1_armhf.deb Size: 4052228 MD5sum: 5697f6e1beac6372c28f2805970bade6 SHA1: 88bf407941462a902782c88980f4bb0cfe89b1e0 SHA256: d4619aa3b60559159fface60a9c76aebd7ae5252d93d466c9bbd115cdb056c58 SHA512: c4dce01f183040662a8e1c52393128af8f64d4f8473c8c418afa7ee5edd9b0fcdef977e51acdb9a74698d84b2ab232f12eec712eaa670b5175907fd07f14879e 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 29016 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-s3_1.0.0~alpha.2-1_amd64.deb Size: 5683852 MD5sum: bca2d9b650c72698727b7a649825de5c SHA1: 28db381d593dd5d3cc198858bd404579bb20fc69 SHA256: fa721a652b957a074dfd4ac9a473c264a8ad08d97c62b569588d1780409f6c1a SHA512: 02e10efa667650def88e6c646fbd5f7b23438ae68a043330f9a80cbe1756948d6c759a9694b2c4314cd42d7a9b8d5770d0473125969a31aaf5572c4d2b8470a2 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27668 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-s3_1.0.0~alpha.2-1_arm64.deb Size: 5374036 MD5sum: b7f79e6aae5810621a35fec3cb9e04a8 SHA1: a5f5cb49a042e97e78bdef95f1bf57eeb476d80f SHA256: 24a847a2b03f77f74df859af6e227ca95d5ec7154ab46dab02067f566e48e2f4 SHA512: 9c159d1e434b53419f7ce86c9cd9562f9ec65b5fc905a50487db35bce2539a4169ef7ef0e6adf0552814d598e9c17a4870e6781172c4619f2600f56159f4fd39 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25859 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-s3_1.0.0~alpha.2-1_armel.deb Size: 5218612 MD5sum: 5bf46c6905c1adb366ba5b766e72de6a SHA1: d983acf344ab4e7c404106b6e7b21af06dedb412 SHA256: 149988c1f09870f014086610b5ac7a5981c5dab065e2687e607b0d354d576a34 SHA512: ca7f82ae2ba29c0679aa832a4fcc87175e917966cac56ad5ea293d1635731fd0bff5b0da0438272e0821d40e9c47c2643edb6697cca21b98bdaeb8e0e10b4826 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25634 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-backend-s3_1.0.0~alpha.2-1_armhf.deb Size: 5274988 MD5sum: e80ec09163a9b45f623c7cb19b0e43d3 SHA1: 7e164b8fa9dfc28680b54e6b46e8cca4863b05da SHA256: 99b5ae521ee7b50b1e1418d15602a3a10fab8fe9945cafad6345b673f0f7d4dd SHA512: 98f71276a3251ff8206abf45c0ccb2a762d9074250d10d0755acd403ed3c6db2a39e4947e9d845c369b697468a939e518c519cedd2c4ea8fdf2a7e1e7054dab9 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20537 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.2/zenoh-bridge-dds_1.0.0~alpha.2-1_amd64.deb Size: 5186228 MD5sum: 85b19532cab379853d2c403d971db3b9 SHA1: 28aff73133bf644f3014d453b2bece5466537d87 SHA256: 7457f607c1cd5678bd4d8c83df59c5cc43856fca8902fad4959eb29e0f02bccd SHA512: 50a78858c4dae0fbff58cbcef36ae685ba436955e4b45390e73ca75dba6cdd23af312be64b661fd8f91f4decc40c75daedf813bcbd3365b66fc8698949e4067f 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18649 Filename: ./1.0.0-alpha.2/zenoh-bridge-dds_1.0.0~alpha.2-1_arm64.deb Size: 4676868 MD5sum: 6e634682a0836b40ccbd3538a485507b SHA1: 07e90279cfc20bc78b1f43c30f38fbc913cd2c4f SHA256: 66ab369fc6fb862535bae06fda29c796b973a800c2d17a4036afe4f7f6153dae SHA512: 2410503ebde2eee2761646ed3637f8c3883c9d28bb2491be7cc9ffbf8d7095e6befa29074e7f838f96b7c8ff620d9b07007a9c222bb89c747bd0f16c7e5e5e55 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19902 Filename: ./1.0.0-alpha.2/zenoh-bridge-dds_1.0.0~alpha.2-1_armel.deb Size: 4972428 MD5sum: 25dab399f206a8873ef5d992c7382bdb SHA1: e2f838a38f6b79c901cd514b9e74d7a35c0e4afa SHA256: 096959f423896d012b548281541855cc480203ae16e93ac1b902ea6c3dabc1fd SHA512: a8836f0c50c6e0ea4e903d29a3ed6ffdc5c6a14b7c58030a4b7119c33e9089aa72b6f19a3969192da392f157b249b99e9aa757ae3f56c45b28598f8f5448f17c 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19404 Filename: ./1.0.0-alpha.2/zenoh-bridge-dds_1.0.0~alpha.2-1_armhf.deb Size: 5008692 MD5sum: 00af3f9722781938070fe9947177f1cd SHA1: 3ac72d5cee5ec6df5971d4f9ddf2a02c1fe86e9d SHA256: c3b61a3e5db60de6ceabec2fbe6942fa374dab48a012c50fdfddb0b869d53141 SHA512: 363793341665f85dabd24904de5590c01ded93adbe06f135d6b89a676eb65ed2d58bccfac19ff24ddb65e02c4c503bb2bd87f4c05a0cf79c321724f93786a35e 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20789 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.2/zenoh-bridge-mqtt_1.0.0~alpha.2-1_amd64.deb Size: 5025436 MD5sum: 4c5ab322bfe114bbab4b92f8ba4fdb5c SHA1: e1be48a2a87f240d46e848c95ce1a3fdee04271f SHA256: ec9121c7c4d3e4203b251e9ed9b96ca1471ce6ae0a88c5fc1e4f33914afb266b SHA512: 2de829df63c08ec0f976964ea2004c18292eb00abf7720e3a1db901112c7540ca02bbeb8796f62f72305ce49f78c42c44bbcaf013749ff7283d9f349e25f2d45 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18886 Filename: ./1.0.0-alpha.2/zenoh-bridge-mqtt_1.0.0~alpha.2-1_arm64.deb Size: 4535536 MD5sum: a9d832d8a29dd7c331abd1077e153cb5 SHA1: 72d7e3f7dcf60d26298c5910ee9a64305c546898 SHA256: 7e46899e78d86e3e340fb44e737ae3e7e943c24f0e32c9127fa859d7970de41d SHA512: 23d0d68b37d6540bddb27eeddec173745f3933371d5d0e01927fb8949dcad9631975ae208ea9357e9f624139fa9aa0052cde374a1cb64cc2db68d2c5b3795bce 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20295 Filename: ./1.0.0-alpha.2/zenoh-bridge-mqtt_1.0.0~alpha.2-1_armel.deb Size: 4815480 MD5sum: 854bb44c1812f8641dc8c3ab552da101 SHA1: 1a5f1e21e6885daa5132188561b8557b6db2c5d3 SHA256: 89daf84a55d02fdd8fc6496364a435da8d5bbad3ef1254566e5359591bc522bd SHA512: 1313b09c55e338dad67b1077ea9dffaede6d293b79b0bd64f6885f70774e5fa3542c62500616f06a8449118adf2903c2c3f6d7292fdf86217cacafdc43bfd81f 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20013 Filename: ./1.0.0-alpha.2/zenoh-bridge-mqtt_1.0.0~alpha.2-1_armhf.deb Size: 4852792 MD5sum: 3ebba96a56fd7432702d217bd169d40f SHA1: 4dd4ff935e42291405ef835a5084d88333593b1e SHA256: 0ff988fac6aa44498cb50ee0625f622e41721f98bd67b5c1086612ce3648809a SHA512: 8aac97bb3eecd767a6653ba6993365dced40bab5761872f0a4340dc8e0f28e9fdec0e6d74838dcd677a03890609f4d3573446e1262e7522dd2799f6b47cb8458 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21682 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.2/zenoh-bridge-ros1_1.0.0~alpha.2-1_amd64.deb Size: 5294560 MD5sum: afe1dfce80fbe7e218015e35a0e58d2b SHA1: 7e3c342eb66a8032492bbb29e140c07b234d2233 SHA256: 2a6d0671ee9d101f3072d37d367a73a3a80f906a8d071585482a8264d2e5e918 SHA512: bd162ceacd12a2d879e050118993c79f45a77d350e67997c6c3d06037b34f70dd493bfe8349297eafa1158e8bee1d12035e7c7a1b5c175026a640915e0b0a117 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19699 Filename: ./1.0.0-alpha.2/zenoh-bridge-ros1_1.0.0~alpha.2-1_arm64.deb Size: 4779084 MD5sum: ecc550219499e6ebef32ca50f584b4b5 SHA1: 9e1ba02ac320236f2219f4257d7c4ec046d2d439 SHA256: 2a9ad92f10c987258239fd79e6d1905a6f091939129a483a38069eda4bda47ca SHA512: 4864894a898204b0510699d19322c16c2fab00d0208843a4725faa910ba2d8e19971651e0590142b620ba45a8e4ade3d390daaf1b76c02ff3c70867993ba2914 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21090 Filename: ./1.0.0-alpha.2/zenoh-bridge-ros1_1.0.0~alpha.2-1_armel.deb Size: 5107488 MD5sum: 1f0bd272c7d70aa78ec8667ef10d9f83 SHA1: 2c57676cc65d5dbb096057336cbb5d12a3faae5f SHA256: f88b003c8649b67d11bff59b8ad03c709869aaedcb4a14e5a18a2323a60983ec SHA512: d0a5d661a2994580382df4d5ad28fe18b9f8a16179e5ce53103b092d78cf1bdb9cd7ab7cccfd28ed8555002de096757273fa368e6edd27d0aacd2f10da79e110 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20780 Filename: ./1.0.0-alpha.2/zenoh-bridge-ros1_1.0.0~alpha.2-1_armhf.deb Size: 5128328 MD5sum: 500062991e2f009975b4af63141e5f22 SHA1: dd18977c022a8ed1c450ef8ebebbaab4a691ae55 SHA256: 5b0ed454a568467614a603e5f4b78e3b26f20bba7626060d34f5713b167342e4 SHA512: 6a4fcec2f007eafe22edf738202f1004e3a51d1304dd675b59bcfa84885d06e513624b9e016f9f13738e5b7e05d15572e9596fa4ae9ea8556c77c6d2062b8413 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-plugin-dds Architecture: amd64 Version: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12826 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-dds_1.0.0~alpha.2-1_amd64.deb Size: 2586060 MD5sum: 64a92a43442c889ec145d5987a9544b1 SHA1: fdf4bcef6d19b5a953453a3a2a0855df180b0fa0 SHA256: 27aea5a30b646e349e863a19d5ec4a04aa350126ad4dd35800ff4456d9458566 SHA512: c07d40978bfce1be4d12ce21d71f5b1ac56bbd6f51433ac30744cc43f7c66872e62ee2abe4378441898722aa1e2a64d10f9a83d4c660acd1df0c73db17d47544 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11631 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-dds_1.0.0~alpha.2-1_arm64.deb Size: 2355716 MD5sum: 02f4cda54d9fddc96a313a2696cbe947 SHA1: 148b26821215db0941c9f2b5b8cdb5816db5c071 SHA256: f9b0ef796932e29152b7a7f2de033db90f735aba889d3961ef030ca25af916b3 SHA512: 0c57203ce06166cc21553377613111cf3e015edd419782a7a01e994c46e34f4f65b1d0689d01f7350234323e0cb67b94efcfa3acd488265673a5e80f5a2c27ef 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9701 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-dds_1.0.0~alpha.2-1_armel.deb Size: 2211928 MD5sum: 3bd8228ce4cad7e92a7b4c6a3df79c5d SHA1: 18438a735f390a8cd1ac36dbbf70290e2c9f7843 SHA256: a9a5b0f466257d1e66ba7a12769330748e4bfe508234cece296876001a969891 SHA512: 1d19b4ebcccf05e709c961b8c5430a4aa416b6e094c4df4eafd3247cf3129a5add2c3f9f60ea9420fbb2a7a588d4efeccf85eda6ed7b6c2e8c1a243f52910f54 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9331 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-dds_1.0.0~alpha.2-1_armhf.deb Size: 2217812 MD5sum: 74a6eedd6151ea6ab159bf32a14026b1 SHA1: d2fadf7a23ca6c4054d6b62047a81e14875f9ae7 SHA256: f7fe92b130f54cc7f12e4f703dd244ec8464fb601ab1020999df7075966951e7 SHA512: 536e740fc80a7db6d53c5cd9a7c26bf90c44f164419ed762a2b6b5e78b1b1ca6942464d6a740d89a9b7d807b9db1eef4affb325175238e4d66eb9a06b84e8f87 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13657 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-mqtt_1.0.0~alpha.2-1_amd64.deb Size: 2879400 MD5sum: 7d5827323312d77efba5e36e38d05154 SHA1: 2ec29cc3d06ae71b849070327dcaa85308bad866 SHA256: 741bac70df52535bdeba8717a263562b5b6a6d53b9e744b60cef2cf558c6ff3c SHA512: ecec74ed3cf57cec9b33edcd15cd1bc2aa23cd23ef28d8c31b28e87b7f011b0fae5b0fefceaa7afeaa94fd01d387bee2ff9eb6da079fbc536d1832048f6452f3 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12343 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-mqtt_1.0.0~alpha.2-1_arm64.deb Size: 2570828 MD5sum: 15fda6782eced4e972bb486458929469 SHA1: 9559c6349d781be4941442d3f260b2220bb79ff4 SHA256: f0898ea0cb71617b3cd23530e1b3dc0ef6392b45430fec1136975d838e29c3ed SHA512: 7a0d3878e1d7aebeb6019224fdd2ecb68eeb94cd99339d6602c3d6e3beffe34f3a0c19d95212f27cf7b375b8907526da79b55621a7508cee5d475216f64d289f 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12394 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-mqtt_1.0.0~alpha.2-1_armel.deb Size: 2644216 MD5sum: 3bd5c2dd2303b95596d484124a74db9a SHA1: 60b66bf8eba8daeb8835cc2c5f6e3fcbcab8844c SHA256: 0fa8c0ba0e62dbacc0a10d7293db05b03cc444fade3e95744fc1441e8e8a3202 SHA512: fce4e3c49d0da73df5fb3bc3a251c6859b9a21154e2fe9c9dbd56a3767ad32db076351755d9fab9dc80e031bfc9aa986d41c5ae13b9108a2af4588045549ee55 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12309 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-mqtt_1.0.0~alpha.2-1_armhf.deb Size: 2688176 MD5sum: bee48e2abd0aafa8affd6b93bcf082a6 SHA1: 3f0d286e1a3275d9e34a6314754166a2cb3fb5f9 SHA256: 803f77cade79b185f1781e567f643abba76f314d794e78ff9ca1866a0dbfa6a4 SHA512: 6f29a0e3591df0f5208b71d518348b52d9f19000926da9bc89f955b45b5200c7f92ee9c8e6745ed3b8227957d3830e04f82bd29335981e7bcc1877f46795b813 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-rest Architecture: amd64 Version: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11596 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-rest_1.0.0~alpha.2-1_amd64.deb Size: 2207680 MD5sum: b9f7f4e2c48fc56d23704e4fada3d862 SHA1: 390e604a017287ccdc7908426f8d712e607f14c9 SHA256: abaac9efb83cf0e3e69a75b653313d3e37f0cb3637e3d76d76387a3bc30e2c41 SHA512: 386860f9dc4312963975ecd2c95ac8b77979d94bd564bd68e55873cd52d50d206be279a9f4d9f92658c1660a5e266b46f982fe2093413391b2ecb564cb518339 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10398 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-rest_1.0.0~alpha.2-1_arm64.deb Size: 2002404 MD5sum: 1c520efa21ecd618263e13763f2de185 SHA1: a61e6865de6b46a931f88e7d6cc4ba0646a716d4 SHA256: 53a9a1b456bb112c534c2c550d5d55d5bfe5c86d29bd6af1b7db4ae43962a11d SHA512: e70a1805f27473328dd0d5e851e1220c28659a1fa3a51468a389672246cd8129642309c3af7522f1eaacdb664462e2cc986c2dbc8695ee29571a5ed4081418e5 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8576 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-rest_1.0.0~alpha.2-1_armel.deb Size: 1876264 MD5sum: f6d921e02786956026096ff62bbb0a8e SHA1: 987ec6e1cf96a5ff58441da7b8ddabd805b13848 SHA256: 1da8684fc2dd9dc39c110f4bf93cc7b0b3de59b3d0f82707e3fdd61ccc6a24eb SHA512: a535a0966ce82d3f5668be44c3fb3c09b52c4e337fc345b59468071a9786022e833f3426e45c5e03bb7bd2ab028e39a3e6343126597e70bea224a42634eff8fd 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8455 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-rest_1.0.0~alpha.2-1_armhf.deb Size: 1863276 MD5sum: c0a258b3d5201856fd28136c08a6570d SHA1: a474bd7a7826cf142a6a4d273d8a36052e2282dd SHA256: 2f1063b20e2742c40492911fee7d9dc09114e4363a7b72a79bb37ef2c67c9bb4 SHA512: 8bf01758993e0c2ff0bcb48358df349169a4641e37656a269479851fb01fd731583205d450d5087dbc34a8dc4ff39fc5a1626a99fa469422b7eff19447a1732c 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15425 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-ros1_1.0.0~alpha.2-1_amd64.deb Size: 3201204 MD5sum: eabad023f38a00b15bc35ee33a53bfb9 SHA1: 8215837fa958afc5241b7d3eb3b12cc80efdd91b SHA256: 050b5fd2099baf1060e0e4533d2cffb03d173e1b9c0deee504b3bfa44a5c65da SHA512: 007ab4e3e12e56466f4c238769c88bd0ad2bea3c1026e357277ce703b890610094aaa1039971636f2ee96f17b1b0e9425f6e5f8dadcf6b3b2fa51ac206a55f6d 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14086 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-ros1_1.0.0~alpha.2-1_arm64.deb Size: 2956460 MD5sum: 8c05d7d4066cdbd0b8fe43d462f341e2 SHA1: 4596af8932c43988f3eb837139daac8d9b03c1ec SHA256: cc22fe165ab0011693fc5168c800cb9439aa0426e2197142badc44895a136a07 SHA512: 150b3c117bf2aee395909d5625e5ed90531145eb295ee079015521fbc91361652818377a8afc05126301a4d09e2f5a76bc8ef5cda141c1101a014802aabdd720 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12294 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-ros1_1.0.0~alpha.2-1_armel.deb Size: 2859224 MD5sum: d8b1787261fa916f07d58b42b2f5d80a SHA1: 83edee75d730c0eb44a9c190d02ca095e8d342a2 SHA256: 3e8130ac2365b54140514b4cdf580985805e63ba57d2fc72997540fa2c665a94 SHA512: 0ea1ca52c23c06e06735ecc4287ff53bb55cf55b6eac3bb63d0bb7188f29086da2062bde7b325719d373fc094e66f219ae94e2297a03887b57bed4466deff33f 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12078 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-ros1_1.0.0~alpha.2-1_armhf.deb Size: 2834900 MD5sum: 687ed026d25d51825610754a9cc1d7f3 SHA1: e65b74b62c4085cbb288540e4def9440d3309451 SHA256: f5645efeb53586ca4621f24b58de739a1c194df56cde2a54c60c7420351b28a9 SHA512: 4f2806508db87e465a604b3fbd2f96c3679c7e406c708c4fe1ac3bb692d9e62e2a7d93234c25b6776754c84741e1b2668f178b00ececca0d40ee1fa6155d7a7d 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-storage-manager Architecture: amd64 Version: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11954 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-storage-manager_1.0.0~alpha.2-1_amd64.deb Size: 2280308 MD5sum: adb1a1ac53cd5a7742c732403fd17641 SHA1: e351ec7552cf710c075f55d8730ff3f09a08af94 SHA256: 24de9ce66e3ef517ad12336093330f3e2a3662542c913876b88ef20449930d86 SHA512: f4ca3a7ed2a9e7396f1789730113f0a840b22dcecd8bb2e945c8185948fa24720ab96f667152db0b66c967e96c98ee6532b5a4a51429192cc1271eacd47be239 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10710 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-storage-manager_1.0.0~alpha.2-1_arm64.deb Size: 2061924 MD5sum: 5db48729c6220d1c26796e82aa12c846 SHA1: f32fa245ea897ee1de7db9789748a475fd827ec3 SHA256: 80a976959f6421fecd5d8db1d5e103ca4c5500f137443393b667255d47fa8bb2 SHA512: 86bc3f3db33b574520925b35a8c6c3537e2b3b4965405c5841715c46f432fd9948cee9cce4173856099dbfc3fce8f0c653f4d65e1c2d6f9fe75a7f3a942f9a0b 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8958 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-storage-manager_1.0.0~alpha.2-1_armel.deb Size: 1962400 MD5sum: 4223e164c9e8dd38e07f2748e824580c SHA1: 93ca215324f6e2fe6f26d527a937147ca40d3823 SHA256: d7b507f0c52c4eb9fa6d0cfd0c82e52fb60497477839295449e4dfd01b2189e4 SHA512: 179bed9123fd123ae6edc28a2b105cee1e6851a0900a807b9672a4b9a7464eb38db24c254f6ba9ec673263b973d6cb68d27d9f548bc931205e9ae2a2a222b748 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8829 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-storage-manager_1.0.0~alpha.2-1_armhf.deb Size: 1950552 MD5sum: 9b313923d2456d5fc1b7ef8aff96c9b4 SHA1: f0c71468777e47d1ca198e6bd9496d054c37d3a7 SHA256: e1dda23442f99f1ded633cb85944e4b331f8438d0df96eaebc4dd6f7f8dd7a99 SHA512: 9594e658894522f700cae61e1f1f3d7064054244294ea8b085a88e649ff20968c279613e2019ef95506378956a5e02ae2a51c6fb885a77abcc2a332bfd6cea17 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14073 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-webserver_1.0.0~alpha.2-1_amd64.deb Size: 2662500 MD5sum: 81711271176efa1f8ce051e339e64843 SHA1: 793e9979108134637ea319d9c1f4bddfa082c3dc SHA256: 770df77416fc5acf19ff34fdcae4ba40c28d84894e536e93f01faefba6047ac3 SHA512: 249f8e8b4eb51505cd2dc5c3e8b1a65eae0327f2cb3d5403795e8e5f9ea9be5979160122b32611ae1210a111836029231ae38c325f5b71f353aa7b6156cd0f06 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13144 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-webserver_1.0.0~alpha.2-1_arm64.deb Size: 2462884 MD5sum: 8f49fb47c00b1e2dba4f7a4b4b995ad6 SHA1: eea4155960cb1ac294a395a0ebdb5244382a4dbb SHA256: ff49d548fff74f6974d438ed01167f80fd648d52a4761cb423368a0c93e3fb48 SHA512: 51eaba2c7e5b53fccb0913b96c2e55faa87fa06f8881eb78d69eef8691a5f919d295376dd08e4f07a52f1e0d59ff68b26f50ed578c4b90582874b31f1691568c 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10866 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-webserver_1.0.0~alpha.2-1_armel.deb Size: 2262244 MD5sum: 6b113129641d4d67c37e74c12023ad70 SHA1: 4857bb87220082d15d92c3e09f49f404fa88bd0a SHA256: d6cbd50d38a7eacce4eb2316207806268fd1b18811260802bc910db7dcea5a37 SHA512: 88545497fa8ef85da26ae21115b89f3b16e1299b54107bd56e4eb11ccb35bc7b39d202a3a5c242a434327b6173e4c49675c09d4d6049bc5d4a7bcdf9a6840a34 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10715 Depends: zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh-plugin-webserver_1.0.0~alpha.2-1_armhf.deb Size: 2243196 MD5sum: 17380f9df7640cbf50c5a958fcfe71ba SHA1: 1638c532592a056386d61e589e2d42944cb81a0e SHA256: f1c7d7aeacb06f2f7c5c3e497488b4550b53e6ec16242a0e1767d0e81a7dfbe3 SHA512: 8acaf87505bf2fdfcb70295e4c369aacfa83537349eba66994f262cac045b3839459ac97a0c0b8ed7c0ed366e446ba0d5b808bc4e82e0ddbb250b7eca963625e 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~alpha.2-1), zenoh-plugin-rest (=1.0.0~alpha.2-1), zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh_1.0.0~alpha.2-1_amd64.deb Size: 17504 MD5sum: 698f433389754b521a87518bb08ca79b SHA1: eb294403aa70e16f127c534c16aef6325ff7f69d SHA256: d287ce8e002b0cbc52ea4239108be69fb073a3b3d0a82746e2fdd40c3c386e3f SHA512: 4a9c609b7e1e24b2fd18469b5a3544067d63ac71d8d3965f1884965d62203525d75378c5d7129bc474c9fab9417ac5365c37522464cc2f30cac5ca3b1bfefded 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.0~alpha.2-1), zenoh-plugin-storage-manager (=1.0.0~alpha.2-1), zenohd (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh_1.0.0~alpha.2-1_arm64.deb Size: 17504 MD5sum: 1e74e5604e6e8a05812f16ce950bf0da SHA1: 0106fac661a22f9e6c78c048f3ba57cd2ca01521 SHA256: 08d9448169bc330560735557475fe0a6529cd2e35697c8719634c015d98984de SHA512: fbe4be000412b966de3c1fb2ca8105d4c07f104b99211f27e42a6b350179f71ae2ae53994b780928c0c18fdf5689cd0c5abf1c5a9e238e3a25e0a2537227c12f 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.0~alpha.2-1), zenohd (=1.0.0~alpha.2-1), zenoh-plugin-storage-manager (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh_1.0.0~alpha.2-1_armel.deb Size: 17504 MD5sum: 6db27af59984bf88b06e5ed5d4675e1f SHA1: 19d5819f02f43ee74cf9a9b00b909d9a09825b3c SHA256: d369b42a95d43efe56d81e5d3ae48ab7c88a2fb7bf0208c256c7d33e55995d29 SHA512: ca506c8b98234259491b2462359873675e8fa5a787fec032f2a71783a0ca947813174155707b5f9aed06422dca1ec8a4b6ac12fbd908a64b272d74cb5198255d 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.2-1), zenohd (=1.0.0~alpha.2-1), zenoh-plugin-rest (=1.0.0~alpha.2-1) Filename: ./1.0.0-alpha.2/zenoh_1.0.0~alpha.2-1_armhf.deb Size: 17504 MD5sum: d69332f6c402379248a91806169d1dea SHA1: 8a254fbbe634e7df71629cf8cc8b5ae2596dbfe1 SHA256: 3724dca5a23a1a9539d63312add271410a49becb8382bc8368f1534059d4bdd7 SHA512: 94876083824d0165621a336082d781a5393ef29b593a83480ab582da0019766ea9e9d13dc2d4e1a95d22392159464518b66410200eac90648cfd42eb53e47e0d 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18298 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.2/zenohd_1.0.0~alpha.2-1_amd64.deb Size: 4472096 MD5sum: 8aab104a5ee3eeb5aeaccf1d0599d45e SHA1: 849e1961309dac4ebda9d32f05e6dfe87866139f SHA256: 04d28c8d9c74e4cf2b87779d30e60de8a275b46d3b0964da7e2b2ae08dbc8281 SHA512: a857a76fb9d76335ebf18944db04f6e739da4e075d58564e96eba8e0229392bf67caa09cb7e6689ad03892ebdf6d2378602212f3b9c6ab27465befac2e7fc177 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16247 Filename: ./1.0.0-alpha.2/zenohd_1.0.0~alpha.2-1_arm64.deb Size: 4000088 MD5sum: dbacd3d533e19c5ee7d30ea3a25381e2 SHA1: 58b9efd81c877687d9be7843d479340503883cb4 SHA256: 91d6f0cd9cc426893d790a832027882ff4f0ff72938421a8c1c3f85b7eb77aea SHA512: f02ab75ae868907fdf46d0067933607681b6786d9b5d788166b1aa3a4b34f32ffc028bdc3efd3941fcbdb3561394ce3d6f69dd20f6025dc4c5169fe8c067dd6d 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17676 Filename: ./1.0.0-alpha.2/zenohd_1.0.0~alpha.2-1_armel.deb Size: 4347844 MD5sum: aa91a9dd1024abade0fe2dfc66aa448d SHA1: 7c2f298209f3a1f4772d212ea126fe1a5bb0c863 SHA256: 08e7f059e6f9b2302e1a0565639e6a9ce369cfe2d7585641c6d059220fe40194 SHA512: 2e5a32a7296169365a9b00d568c0379847a84516677743a5f73ed27897ca85daa6c25036904f719d2de3582cc62c2267680b595b18859e242afe1f151f228485 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 maintaining 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 successfully 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 deactivate 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: 1.0.0~alpha.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17447 Filename: ./1.0.0-alpha.2/zenohd_1.0.0~alpha.2-1_armhf.deb Size: 4397368 MD5sum: c433fbc0be343451ffacae1635818f39 SHA1: 7c4853aa358d4a3bfb40d0d9c36b5465a6028243 SHA256: 769e5148022ad9a655800fb301e7f7b1d3d2910632b93439de8a8dd4cdbace44 SHA512: 1863af4942343cce44fe243f70fc8c71862ac76092d2260a41dfaf62494651b002d5fde17492579562308534336b9d5f237b0f7ec12fec2c68f365ff5bb627f8 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 maintaining 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 successfully 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 deactivate 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-plugin-rest Architecture: amd64 Version: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11601 Depends: zenohd (=1.0.0~alpha.3-1) Filename: ./1.0.0-alpha.3/zenoh-plugin-rest_1.0.0~alpha.3-1_amd64.deb Size: 2208148 MD5sum: 0b129b76ae175d80261b4f5c8ca3f52f SHA1: cde1378446d4b94c8cb6a5bf5defd9277582c87b SHA256: 8f228d1758a2e1cefd49952bdebb967f810fd51a0761c2bf41dbd6b7a23f6fd1 SHA512: bccf391d972c4d4c8845eac22d4de1ec3692ef66cd2d239300c5162c256661fcfeb49be16505255f1434b6fe23c4a4bb04e7a06cc7920fd2ca19102804d0bb83 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10411 Depends: zenohd (=1.0.0~alpha.3-1) Filename: ./1.0.0-alpha.3/zenoh-plugin-rest_1.0.0~alpha.3-1_arm64.deb Size: 2003412 MD5sum: a9ceda08e1c1ed92abd353af2e96e1ac SHA1: 6a127a75482c2f2a61a214e0ea313ec67b6b1903 SHA256: fa109540ab34c2179f9ca082e3b584ede4ae04a7784ac2338249781db7e9c5a3 SHA512: a192707e2fac11bc9b40c48a33fe8d9426179f9d0644a79fc5cf342f13da375f9c307484737a7bf97d226ea25fda17aadfc838b6aecdad4d59f9081a78186353 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8582 Depends: zenohd (=1.0.0~alpha.3-1) Filename: ./1.0.0-alpha.3/zenoh-plugin-rest_1.0.0~alpha.3-1_armel.deb Size: 1877184 MD5sum: cfd5bc355f9e0fb22d871ef69bfab3fc SHA1: 3a69ec51ea9a11383df02dcdead88e979579ffef SHA256: 53589b59187d03a24565d768ad4de00cf3fdce6a82637693323fa78b29be682a SHA512: a1cdd64401c56ef8fd1b0e694298da5732460ed59adfa0bb57d9044750b9ba1439d15229146d093123ba5af8d9ffc64d7aeced87eaf846df9181231bfae797f8 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8460 Depends: zenohd (=1.0.0~alpha.3-1) Filename: ./1.0.0-alpha.3/zenoh-plugin-rest_1.0.0~alpha.3-1_armhf.deb Size: 1865352 MD5sum: 1c61fcca7d64c5a36d6139725c8a283b SHA1: 4e35bb938415d80208f39c9ce479941156c7246f SHA256: 47e83b1fed95454cc1cf6cad1014c1afe3b6fa799d3feff500e4101a746cd3e2 SHA512: a79bdca8a9ed271da47d664667d43e2696498dafef35980a4d9bc7fa24f1aeb4d4c1e617145f9117653fe615c429ad1a520ce7c63f81a41f6709cf4c31384202 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11955 Depends: zenohd (=1.0.0~alpha.3-1) Filename: ./1.0.0-alpha.3/zenoh-plugin-storage-manager_1.0.0~alpha.3-1_amd64.deb Size: 2280956 MD5sum: 8a070e23d7514ddf705649437ca07cd7 SHA1: f9165ca8c4522dc0073bf4113880b55297ab3057 SHA256: 58d0454131b85287a6591cb867335cf4568b38eb1593966fb70216482bd031f1 SHA512: daec6fe54f3e2f24a11fbdaf031e24d044d562c87a75a05ca159c0ac5e469b30668434d1f4a1b60b43bb85e0c144b098a6e676f0f3cc977c199b1b202856c94b 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10716 Depends: zenohd (=1.0.0~alpha.3-1) Filename: ./1.0.0-alpha.3/zenoh-plugin-storage-manager_1.0.0~alpha.3-1_arm64.deb Size: 2065160 MD5sum: 1904e8da557f1f9bccd96ecac3ba8bb5 SHA1: b986007b4ac39bb260c795efd21f3b10184e5db9 SHA256: bb861f7f98de31f62aff9c3b799796fe773fa372033483754f681324de334b6c SHA512: a2b50554d1676184bccc6362fefb473bfb35ce2f6420807bd264fe4e8c0af120ccb4037606211b33708a91306aab6fff5cb5df8d1713e716f7a65a0eab6e5d31 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8964 Depends: zenohd (=1.0.0~alpha.3-1) Filename: ./1.0.0-alpha.3/zenoh-plugin-storage-manager_1.0.0~alpha.3-1_armel.deb Size: 1963736 MD5sum: 5b0855f16c150eee2573d41b09fd2e26 SHA1: 18667b41006af5deadfd6688ac0523f11646a295 SHA256: 1d50b58ad9b985352c31bd29fa8e26136b93b44c5a32f6e4c7dfff0935c002af SHA512: fd654c88df2fd543554e22a2a490df8388f5263cf2b7da60ccd84520fb438de9e893811b6860b9dbc60914d725f54801fa38c6a307a9cad9722fedea58083a13 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8835 Depends: zenohd (=1.0.0~alpha.3-1) Filename: ./1.0.0-alpha.3/zenoh-plugin-storage-manager_1.0.0~alpha.3-1_armhf.deb Size: 1951440 MD5sum: 1d869b8e79fe6743f49ebeadee355414 SHA1: 3db3f078de95a459cd579f759302bbdc82f2b773 SHA256: 6bce6714ba62128c13051010cf35b539334c454b785e145a2c35727b1edb7a5f SHA512: 538b529b6b425716aba0b0ad2b4a2ffb84fa6ead2b96777bf4b6a76a2dffeb60c09ad91702d5222022e3b4ee15fe6dab91f2b65281070c830b322849277e99a4 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.0~alpha.3-1), zenoh-plugin-storage-manager (=1.0.0~alpha.3-1), zenohd (=1.0.0~alpha.3-1) Filename: ./1.0.0-alpha.3/zenoh_1.0.0~alpha.3-1_amd64.deb Size: 17296 MD5sum: 0197fd07c316d97ae645c01ad359f1d3 SHA1: d40a854f852dd8c8ccbf58a2d479e6af154f45bb SHA256: 6f39fb32dc4701714a442307668de4762f80d52f1bc564617f4213332efd8003 SHA512: bd427b7de271f5492881ae7c03edfe0a53f259bf95534842e303ae1d98d332e6a12e6a883a85ecdfd0686b091d22e870bc87ef5506571c92165f3b5406710372 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~alpha.3-1), zenoh-plugin-storage-manager (=1.0.0~alpha.3-1), zenoh-plugin-rest (=1.0.0~alpha.3-1) Filename: ./1.0.0-alpha.3/zenoh_1.0.0~alpha.3-1_arm64.deb Size: 17296 MD5sum: 2c2a3c7ef91e2736499d63f637a9cee0 SHA1: 13a30e2dcfaa8ee35623181fb0c1769b344d09ad SHA256: e902ab4337feb430095e7506d7f6e25049735ae5ec0e7d563b4462907bc80961 SHA512: 9dc12d96cd698102e6461d1debb96a33b5b1dc9c28a6a6e952014c36b296119c3aeed2c0e56f9c673d3c6bfe9eff2a29d282bcaaaffaba77ee482faac94170c3 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.3-1), zenohd (=1.0.0~alpha.3-1), zenoh-plugin-rest (=1.0.0~alpha.3-1) Filename: ./1.0.0-alpha.3/zenoh_1.0.0~alpha.3-1_armel.deb Size: 17300 MD5sum: 9f67c0d310baf3e78f72806ab9f4f127 SHA1: 98154f1e77c168559b5468799b41ea00f438d619 SHA256: 46c9cbbbf884ac53acedad7cf19d5f2830881025f3c2ec20cb7ffaf8558b3e1c SHA512: 0be037e749ac0d590a1c24edf870ceca84f1d0740064e40769ee4cd79cf23e267bed3d2d7367754dccaa4e8b93f6a9b79a3f14c11a1b25b050874e11fd563633 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~alpha.3-1), zenoh-plugin-rest (=1.0.0~alpha.3-1), zenoh-plugin-storage-manager (=1.0.0~alpha.3-1) Filename: ./1.0.0-alpha.3/zenoh_1.0.0~alpha.3-1_armhf.deb Size: 17296 MD5sum: 4aa67a81e841f6237a9b6533efd65516 SHA1: 70b4c390bbf49a6053f15f73af5880acfd6b0d73 SHA256: 8675b54cc946f5718cb68353a3f40b9ac9cf3f86e4729fb6a96666993cfefecd SHA512: 73d7b5cc5c09aef7ab4a1e7b7565612a3ec8e12c4228a55abe7565d69731fc12ffd0efa624cffca8849f4461387c5ca0962486ce31360c74b5e571222625c201 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18355 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.3/zenohd_1.0.0~alpha.3-1_amd64.deb Size: 4483212 MD5sum: 8bf50887c2d54ccf1a83e4e31f392a27 SHA1: ecf6e2f315811507fa5ce36a142363c152cacfc0 SHA256: d784bf528d9adc000ba3c6ca1ff3ebc07d33bb16d9c6d5b2983ac4a67ec88c89 SHA512: c0c0d989a03132a651d13a3db12f9e5a8dc1cdfa19ab4cda38b20779fce12b1d6ebdd4f625cdfa2f490e187431a8b62a769a3d69a4f5c390a28e66c504dba4bd 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16299 Depends: Filename: ./1.0.0-alpha.3/zenohd_1.0.0~alpha.3-1_arm64.deb Size: 4009000 MD5sum: 350ad920d8ae98aeec80cc1bbc078709 SHA1: 850625fac276dfc4389bfc265995dce246c2f1b0 SHA256: 8ee722a19f8b640cf4c07669337fb3ff37d7c6613b4a4a3fd581863eb6ab3089 SHA512: e6319fe7fb65f8336b4d9a330646333cbf0feb49ece068d9b9d7f691518a9a349a55e0e875d1172edd0f3a64938b43e15c24ca7b1f2e6c369df1c2ed9b20ec2c 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17730 Depends: Filename: ./1.0.0-alpha.3/zenohd_1.0.0~alpha.3-1_armel.deb Size: 4359804 MD5sum: 75f8a64b6e6e3a812eec78468a4d0c7e SHA1: 257db53a29c2f00899809dd554b02897e31858bd SHA256: 9bd0e4e6e641913c49f2e38307e99bf58a91738a6b793ff14982ebebe5f5946f SHA512: 6402b31acfed7e9b5bb4a2c8c4d797b894551fb655229f373eff07b59878d9dffc0828970fe979291de9a911c2ca09bad8d85c86b85f50114dc4fa62489560a2 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17501 Depends: Filename: ./1.0.0-alpha.3/zenohd_1.0.0~alpha.3-1_armhf.deb Size: 4408808 MD5sum: 8daefd7ad6aec3ed63e37cd685cf3d08 SHA1: 7380b1ac016055781da59b1be2e16f7718669c28 SHA256: 903b53163d299399d4e50248e958f43ab0b5cbd3c885ab8d125926e20868fa08 SHA512: 4d38aabdbbd0e696d4963e9de546188e8fccd6785cd039cc79a0d599ea410c21ce197e3f2c1e7d12403eb0aac69468d36c22e06712fc666bbe266491dc07b8bd 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21018 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-filesystem_1.0.0~alpha.4-1_amd64.deb Size: 4651336 MD5sum: 10b0b1096279c951f107ecd6b4cbe431 SHA1: 7c4ac6b1ab21a2dd775e54067d894e5b7e01fcba SHA256: 1814bf4d605899b2ae1b3663699f7db7f48d33aed305766133015850fe6056a6 SHA512: 9d665621972dc645cf344caa8472682e63e96394706f1539ed1beb65c607dd12e470e60fd7ba7a47cfcdeb866b6774b211e6fed06ab88f831b2495db9951d284 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19153 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-filesystem_1.0.0~alpha.4-1_arm64.deb Size: 4184140 MD5sum: 36970553f5894e17e2ffe865c7ece6f6 SHA1: 9a24ab2cc11007523817dc413bf720605b793624 SHA256: e6392c5a5a3b53a9607a7521ace3f995439844261b6258d2ff37d876147e1a23 SHA512: f36145432bdae4901a453fa18dd406396105ae62e2568ed52957f6b614aafbe62309953c99fbb418dc4b40a4cc92e8db354ecf621362d3201ed271c4758820f5 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16761 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-filesystem_1.0.0~alpha.4-1_armel.deb Size: 3965500 MD5sum: 085be4256790e092f67d871fa5736983 SHA1: ea0993d72eb01dfe2317af1204fe22074ba91b27 SHA256: 85ae0954794f2edbad1135ed2cccd398ebd88f48b1964ef01ea8d39dca83840d SHA512: ef4f72b379174ca1a45baf32fbf3eae1211f69c95ad4c24710f95feee23d51a84bbe6979783847aaa8be9fe282cc677ea603789aeef6b0b9f813ed2f144ee547 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14871 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-filesystem_1.0.0~alpha.4-1_armhf.deb Size: 4060912 MD5sum: aa3a6af289ad18472b97d640dd51b6b3 SHA1: 66434348389684e78196c17d5a66b1b8ffff3627 SHA256: 93a004373fef47170bd372dfc4fd0cb34057f6d6cc2af161c69c2581a26b0687 SHA512: d3ebe7327b57c1ac2de927e917f94adc420f1f74586e69ccee30cc18d87a62b5720a6bf5b35c4ed46811abf6807067d706b953e17d4823f645d9a36b28506bf1 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15725 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-influxdb-v1_1.0.0~alpha.4-1_amd64.deb Size: 3125656 MD5sum: 86f19cff1fcfc8b9088845b6fe701f52 SHA1: 3f11c679aea7d84320fa9ad12c0a30617b1f1deb SHA256: fafd5b3a6f270e80314f47f3686315ea82c763eb2d804fa66edb5b67be2bbd4d SHA512: 3d071df7a4d2686eeefcb40b002f1421b36f681d90abfda60fe60ae486083c24ca8f5ceb80e7f982722eab98ebbdb69ad8df448558abf91f480a7c7f8cb131a7 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14118 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-influxdb-v1_1.0.0~alpha.4-1_arm64.deb Size: 2812964 MD5sum: 145dabecb12984397af3ac38b8146291 SHA1: 9a550e03f25a4acea79c6620853700f98073dd53 SHA256: 7d88d9eca204c34c2f19c84a63efd22d88f8f6d3f6cfd9b86cdef8062cfc1dd2 SHA512: e14bac23a6f7665b73c85dfe0d6938e6709ba9f06e82ad155edf9ae9f9a531dff031f97da3fa23c38df785d6369cf1f8abb2bc6b78fd8a404e5e1cbd3093cb76 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11944 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-influxdb-v1_1.0.0~alpha.4-1_armel.deb Size: 2568008 MD5sum: 44f026f006b32ca27a0df5159a6140b5 SHA1: 84113a8aa30c09c4443f94ce5a78e1ed8570a256 SHA256: 9a16c1f0df693479a4b1ab8750a71480cb27b49ec1f7d54d89a1f5a06c7bcec9 SHA512: abd20df2fcfe88b8c3f630513beb676c91e889aec3f8374b2e3cb6283531c0e62ec90b5e7c5ebc9baa6421113f36fc035d9edffaf82bf73d6962fa058f519602 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11807 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-influxdb-v1_1.0.0~alpha.4-1_armhf.deb Size: 2559328 MD5sum: 470f7ec8782141f7932afea8bf1be6ef SHA1: dd8902fe84be2bb449ee2a0f7b47381890e7053e SHA256: 681ba9b4581b980f18d87c0205237a0dece4130b66d9bae1bc2fc06389b9c576 SHA512: 0b8114667978c0553149ca1107a51607b7d369593e45fa6034b4288ce91a870bec6083d8669cad0bacc2e1b3b5d2ed7322a430fbe88b3c27c02f61b277fb0391 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17474 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-influxdb-v2_1.0.0~alpha.4-1_amd64.deb Size: 3842688 MD5sum: 6fe618de28eba936f01bce2c9d12d340 SHA1: d66a51a84620e473c478c94745734ad2854c66ba SHA256: 39f58f9a6d522baebf0659f7279c5955120328d5d0afb7ffee047e71a4597ccb SHA512: 83fac65af759ddd4516f4f687fb1349a23c6ccdd1bdf9a01b7cfc5ed20c4a067faee752d6f1f67118444d74092dcaf151436904441519e02265b41308d2604b8 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16516 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-influxdb-v2_1.0.0~alpha.4-1_arm64.deb Size: 3530180 MD5sum: c70d2daf248754fe1da0e7c4cb8ec0ec SHA1: 9fba0cb2a3f94bda8624a972ac74025910cd4d2c SHA256: dd1440439b6995c116a2eecbfdad6c006869d06985ca86837e43c75f5a06f448 SHA512: 2f927f0dbcdd0b29c431615606cbd4664c18133ae4516b6e2cc51a5164005a1449653415aa0546577473133c192c937473a1506eae4c5169e0a27d0fee4ad91d 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15821 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-influxdb-v2_1.0.0~alpha.4-1_armel.deb Size: 3513980 MD5sum: 523b4a541d7998950d5246a4e8945996 SHA1: 0ddd36f188b78c2712be014cd630c6123f90b955 SHA256: effa6e7cb41ba93969e87b32682a19e01d9cf1d4ae25aebd3584f3c5a10d639b SHA512: a7effa6f9c7823183135c2e06610fde9375b135884d82f0cc19dd532a27042c02e6e519e45875709cd850d2861cc62f3c7e5c138004f8fb03a704d4e95c1fc2e 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15707 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-influxdb-v2_1.0.0~alpha.4-1_armhf.deb Size: 3555224 MD5sum: 9514f1371aace920e27ec8729834f702 SHA1: 753ecc95c30ea824ac20912c93ff35d056ab6c1a SHA256: a3170e64588786cb4671044682226b4554696b999dd1c935e13ef5d3a7686f4b SHA512: ba52cdcc7c0b06c990de5646c5b24c9f0fb5fb40ed695a0385d183668b92895b5cd1a72d38f4eb014734b1abfb1b2d12957f4b7a610d5682aba0a579457e328d 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20638 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-rocksdb_1.0.0~alpha.4-1_amd64.deb Size: 4599512 MD5sum: 63ddfaa7f4b675d9d2de1ac3d257fa04 SHA1: 524fbca52e7e66923fbeeb7044208cbe52b6d1d9 SHA256: a0bf264229127d91ebbaddfc08cbb4e05fe6a9532a12dedd1d2cff295fa8f18b SHA512: e7262f87e0af54adb809be02a6f4d7f1b334524e33336285c0690f8414e762b7b03ac9e02712b4572a7b1c1ffc75104ac3b3b14e72a4ba686af3599a03829d4b 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18682 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-rocksdb_1.0.0~alpha.4-1_arm64.deb Size: 4120912 MD5sum: ec16241d4e18a3810fc59ef6fa53c7a5 SHA1: 3b33ea6f56df0b8555cb23e88034aa7e5b30b06f SHA256: ff24377832ca7e7a783c80110e7389acdb79779cb823d519bfca168b85119952 SHA512: cad4488433ed13138e05c9a165f813697e9799652026d479cab40f6734a5d560edf7848748943d5e11127a126a665e7f9bff3ea5e9a73a0dd788c5b63a8a62b4 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16406 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-rocksdb_1.0.0~alpha.4-1_armel.deb Size: 3922280 MD5sum: 6bb46e9b61affbb55d3db9c348338bb3 SHA1: f0f97228db2a0a7b8b7699555dd3371a4349d866 SHA256: 5d5debe00846f4878d9262c7c4f14eef4e7ccd16d115c528c72bf6a6ab13f807 SHA512: 96ee231d5359c5ce179a41f72f67b067104ecc593566663f3681f5d79e907df967e47f642d7d98f8d053efec082f62353aee3802e9075ee0da346898e10e7e34 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14478 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-rocksdb_1.0.0~alpha.4-1_armhf.deb Size: 4015336 MD5sum: 7b8b390e0f79867de24ea5e619d74849 SHA1: 55d9d75c22b06943501fbeef3f1717d9f7ae87e7 SHA256: 4ac5c205eac66e10669b4fdbe89399c53347aef6f89c4db2a23f954d1cb8ccd6 SHA512: 7f0151bfa91d394a6763905f6482a1b4bec17527f72ef87c3fbdd19aef21f79f5c3bcff0af03c054540daf8d57e97a506c493dcc58ba127ce8b2f3aad3f9a4ac 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27312 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-s3_1.0.0~alpha.4-1_amd64.deb Size: 5505852 MD5sum: d2b5f3206b862602394c0e3bebf5a1c1 SHA1: a5b67264b1f9b4a21ad6ca92e4f2f042c9f647d6 SHA256: 857fe8791b2b2c35affe182eebe0ea20591d45ea1e4cf3c21c4ce7fcdf0e0b17 SHA512: 09db0f1f22b75f8e05fa2cfca0110e7dc6d6e23cf6f98b25fe9e556b85ff025c944dcafea610978086b853c157cdb7f42c42e4da45509b3bf85d6817e673feed 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26571 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-s3_1.0.0~alpha.4-1_arm64.deb Size: 5229800 MD5sum: a6cc3dea597b6dfeb39d75a535590ee4 SHA1: b79200b6c30e7b5035b624d205e5573586645171 SHA256: ef692f9a7c3d64b2d17124e311df3489d61ad2d11061921568b88feb0c2bf867 SHA512: 857ef5b56e940108d9c2f1ab8dbe367c54558969769f168a8e266ec6b4d43aa77427b1c0496d9b5f7b21c7b6c64678fe90085e4bfa3c0687ba9a1368d5b2dc24 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25355 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-s3_1.0.0~alpha.4-1_armel.deb Size: 5092760 MD5sum: 8b655237101ee75ba387fc3436b8dddf SHA1: 130d87b8280e97b44caf1c3a9b5096b3e220bde9 SHA256: d5f9b997efc5d31b6968e4d69cbe8c22c757629988df523a51212de068da0a50 SHA512: 98d745cc88e3ab67e5ce4498f18b067ab802794d92780007d104ea2c6175136d55ee67b9c5059f977b0a9086e9713d097b9c929b9f69f5066504ed3d55a3809b 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25111 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-backend-s3_1.0.0~alpha.4-1_armhf.deb Size: 5148128 MD5sum: 51fb7cbd0acadcb2c911f363ff6938aa SHA1: 797b32a5530e2a924f0004206c08caacb1404526 SHA256: 51067a3a6fd1314f7751e679a810209fbdc472452252b759b978145ffeef1c01 SHA512: 9d73c03b6dcb7f912003e59ab13a77d872e5a01846f1f73da77a3c25fcfb47864c0677104a4539ff9ab8a2b96aca4445ad7f867267ab95e5ce55e7f83e35aac7 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20529 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.4/zenoh-bridge-dds_1.0.0~alpha.4-1_amd64.deb Size: 5167616 MD5sum: 67116e586de38a346f855588c68ec008 SHA1: df7382ee93a87b796b5e7f3f866043fc546276ac SHA256: d25e2a1b5c3d0cf3c5fef37dbfd660190345908bc8543fed947bbb2f4fdc5354 SHA512: 7aac0fbc19b3f2aaaaace910c6c7c875d3f56a7235729ff3b8711fc5a5b5a48b4499453b0689e0ad636d29f95ada759fbe89a808a1e14ee73c56b88df7e9da7a 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18646 Filename: ./1.0.0-alpha.4/zenoh-bridge-dds_1.0.0~alpha.4-1_arm64.deb Size: 4659100 MD5sum: b37767e52f688bccbd07bff602d0646c SHA1: 7960a135e95a5a8996ba746aecb2915754c7f06b SHA256: 2c96b6bb2a0af0e33f258fbcb9ef72a6be3e1b7fad8982ef5758add1295585d2 SHA512: dfeb74ed5d2617211be00a13534b10fe964fbeb3b12819bf4b3d47fe3f08f8f0c67082419211f180976f2b4b93c01e86fdd5db618b10f44bcb101052af084cb1 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19889 Depends: Filename: ./1.0.0-alpha.4/zenoh-bridge-dds_1.0.0~alpha.4-1_armel.deb Size: 4949776 MD5sum: 24f83e21383d414f8ea7a1a88b327c4d SHA1: 055b33071594eda6ad8d6c239c729d60dd91608f SHA256: ccef3f9c44ec58ab2204b579873e20049fa5a7e9ce7c6bf2f65c9b147706f915 SHA512: a68e24a5e156007ab3f3807c6bf2e1729f694f93ad9e9dc74c221363884d74f11a94839c082311c9fff0850ee1d8e35569a20ae3d2406aa5a774f15f1be3a633 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19404 Depends: Filename: ./1.0.0-alpha.4/zenoh-bridge-dds_1.0.0~alpha.4-1_armhf.deb Size: 4998176 MD5sum: 56dac54bcfb0efd3644c0f80b1a394f8 SHA1: 506997e5c65a1ea6c60f5faa3a5ce08757cf12a7 SHA256: 5289bfb25e3dfda82d2e91d3f94bd7ae63a207aa3ae49397845c6e92d0c7aedb SHA512: 23b3713f5082c230e411d88be503bbed9343a073dfedeb392329a6b0c9a6edf2051a329d4ce680ffb419ebd9597fbf66a5da3e62df560b063926fe8cb67fe46d 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20387 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.4/zenoh-bridge-mqtt_1.0.0~alpha.4-1_amd64.deb Size: 4957056 MD5sum: 6d670a5d48f198c65701d898c745c8cd SHA1: b7de47d02f5c931897bb1755215ed339289eb8d3 SHA256: 3a0c62c18ac73a3221550ccae06795a955b2b0f1e880c0f867f03fd0b1d5408f SHA512: c6247b089dfd2a571ae2bedd102b1b49f38a47d7c4f618754130c58aa2f2c9df25e33192c6baa8e2468349578719d5dae9c548e02d838aa373830f275c9c11ca 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18469 Depends: Filename: ./1.0.0-alpha.4/zenoh-bridge-mqtt_1.0.0~alpha.4-1_arm64.deb Size: 4461760 MD5sum: 2b261500cb26846a37f62ddb57453fcb SHA1: e6cef4346804adb9c5552ca8afe14b5635823ae7 SHA256: 34179e9f8730f9458fbc8134bf84e115ae00415aecf924770cbb1500433b5167 SHA512: 9da29960066b634aff0851496b0748183f887fd4a548e4306b2e54ec8b9ccf7c8394440166986dd909e754b59f4640c5de69104537ca796fb340cfda33034b8f 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19878 Depends: Filename: ./1.0.0-alpha.4/zenoh-bridge-mqtt_1.0.0~alpha.4-1_armel.deb Size: 4768152 MD5sum: a8c720b87854461bbcc1f74b77a5770f SHA1: 153c34baecc54e8e61ec2d52a900b02d0ba2c9a4 SHA256: 05bf7335cf96aea5337e80189873acc4536df8900ff808bc8083e05665f60305 SHA512: f7098b0a23e139921163c5443a6cd9301d12b6b018fecb8e131de48b0d8e5f6ea29d6e3793bed53331d2e7a5427ac46a8017c71e80a6fec16079434a175728a2 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19607 Depends: Filename: ./1.0.0-alpha.4/zenoh-bridge-mqtt_1.0.0~alpha.4-1_armhf.deb Size: 4793424 MD5sum: ef4a7c45cb1f387e79f56aa718b158b5 SHA1: c21ae02c5b010b72168cedf051ca566f5bcc5792 SHA256: 6ab9a56b2c80700de5a6032f8603272aa84075384fbac9322e134fe2d10b7ad2 SHA512: a6c2d4dd25206df476292c454d0e104efb180941e3310405455a4a2436e704f096dc61c1c654f0add814977e03d32bd784929be172aa92c0a54c90cc01e10f48 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21818 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.4/zenoh-bridge-ros1_1.0.0~alpha.4-1_amd64.deb Size: 5334696 MD5sum: c34856e42d38478bf11e6fdcb6c89c97 SHA1: 9b058ecb5fe82fec862be3937dfb6e6767d395f9 SHA256: b8bfff1ce15a45c32a8cd2750d837ea78bc9d1d7894316629bfae78aee187846 SHA512: 20a095ea7171c1577be8e0932ec0b4de0d40cf50f41db57e967255f8f4bb6e08070b4c7bd5493bd4d51dc494587620f2684434db47aaf60efe2d07e2f17de8d6 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19829 Depends: Filename: ./1.0.0-alpha.4/zenoh-bridge-ros1_1.0.0~alpha.4-1_arm64.deb Size: 4810784 MD5sum: 9bc5800d13adff98ca8b894cc4a62439 SHA1: 42b204b67f01e58017e6bc17f96a6023dd2f1a4b SHA256: c8935e7298e79f05b2035b9b900d765fe1b2699191acdaf04a76c01be6144c60 SHA512: fe7904cb54532d81df508cc1b637823df282bd9454482cd07dab3739277464f0d4c6a0abf84bc1b89493ebb8c968081b8edd98c52095dc3b6c9b192c1c307494 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21227 Filename: ./1.0.0-alpha.4/zenoh-bridge-ros1_1.0.0~alpha.4-1_armel.deb Size: 5148464 MD5sum: f99fc09caac8961d2cbb625228a5452f SHA1: 9885f0c144087606b283b80d2fb2f3c7a46fddf5 SHA256: 8e4f876aaf50b6ae882a45138304481104ffd9c81f7504c93c7cdd7f6cf0510e SHA512: a1c7924219ddc34bb2d66ad5b0266de16914be67ce14685e444b6344cf7ee5fa749d65d8c311d5be3f2ebfe54e8920cc40bd9c9f449745b054d6103f93b385b9 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20926 Filename: ./1.0.0-alpha.4/zenoh-bridge-ros1_1.0.0~alpha.4-1_armhf.deb Size: 5178188 MD5sum: cc292557609f7e2813c1ee7c3f5fdef5 SHA1: 0423346f93e40e5155e293c2fe61845725ef2ce4 SHA256: 0ba7aa2ca4e93430b3448ed528a97ad71ab44240644d836c4b2bd7388383216c SHA512: f08e4f79e9866b6b320b21dfff746edb23e2e0e5a0cbd90d536a502083c3cfe1e5e58f272a84714688c68bc363bf813b610fd80c359c20506f009bd9423c5c35 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21164 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.4/zenoh-bridge-ros2dds_1.0.0~alpha.4-1_amd64.deb Size: 5297348 MD5sum: 7f9fb7bec4690ce8bd31abd011430ecb SHA1: 18cd1f93aa1e3e0065c55e017f200e4770a4284a SHA256: 3b5451bd2423718cdce0331d30bd58f6d6f72a7278a30dfb754bac2ffbf2f3a6 SHA512: cc901d07d30f8585a371e9bda83654993bd61696fa41a8aabd2edaef7d5d0dfcf6e71b3ebd97c4d2a2d28393c3901275ca0434a572675f57007ed2ad8507b806 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19238 Depends: Filename: ./1.0.0-alpha.4/zenoh-bridge-ros2dds_1.0.0~alpha.4-1_arm64.deb Size: 4785660 MD5sum: a553659ee936a319ac862c78282de4bd SHA1: 798a7177e1157aec5f76cc42ab13b7ec1c253768 SHA256: d359402efdd5bc55363a385467b405dbca3aa666435958f481164ca5764946bb SHA512: 09d13db329756db3ebb29e08c8f4417691a645c65918c7941eb579cbb47140aed5e894c4babaa6a4e568ca5b42cb8dd3763df0c8540836ae93108ee8b5dffbb1 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20487 Filename: ./1.0.0-alpha.4/zenoh-bridge-ros2dds_1.0.0~alpha.4-1_armel.deb Size: 5076048 MD5sum: 8370b024075311b01c76d69c134fa639 SHA1: 004676136cf719d1c38d97ff63a35a41f198a32a SHA256: a0ceb07a804f6e5344c5b8d48f2d67767af787d33372211d6a8cef6165948002 SHA512: 2e94b1eb60519e2d851573141292c933df40995be291370d56edeb46ba38923a56931f0cc2ccb8b6dd5a7a03d9f61b29a39a07963dcdc0da693dcc5120b724c6 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19997 Filename: ./1.0.0-alpha.4/zenoh-bridge-ros2dds_1.0.0~alpha.4-1_armhf.deb Size: 5132820 MD5sum: 84cdd89634c50e63ec0263d82d8850a2 SHA1: 1f92a370b34100576e658d2251006af128354932 SHA256: b8539240a947a095105ac1099255c418ccdbd342723471a0e7b9266b63867479 SHA512: 960c38e4f65953a0203930264552159db97ce66dd8ce4c11dd2ee875ba1520faeb8a971e2ccf253011d58f40a6cd633195ae754002967b2376a3b054204dcee3 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12835 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-dds_1.0.0~alpha.4-1_amd64.deb Size: 2586220 MD5sum: fc36ea453f0a4b72337e63ed8c596371 SHA1: 4d638e9ba06707894050db6b89e96d4ca8bbdba6 SHA256: ecdbca62824583fc54164dfa8c77b30cc2cbb76a40aafb8134bf1949d3c9dcf2 SHA512: c463eb04d8595733e47c0b756b17e6146d043caf6fa4ba42ff5e79262a092e240456a431f5dd0a33fd1145302f102491be7ff61b66e9feb39c3cc520ca275c2e 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11629 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-dds_1.0.0~alpha.4-1_arm64.deb Size: 2356884 MD5sum: d47350969d6ce269fbb9d57cd200242f SHA1: df53f8c7c9f1dbf318aa8650a360c5db9380179b SHA256: 593b88508f981efd1dc781f06d11c201680e186cdeefe8f8d616c67356524fab SHA512: 5d8558d261877db3d26f2e742ac8e4293f530e985be0ef3557426f1582f19cba5ca6bd1757f4131708dd1eb2f28eac7f15d1cadf4664c78e72a6be597848ef13 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9702 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-dds_1.0.0~alpha.4-1_armel.deb Size: 2212664 MD5sum: fd583ae718b7ffee5e38d5862b40271d SHA1: d713e1954715cd0168bab7ee090ddefaec0404df SHA256: ec0f3f3217710aac792f77f32cb24e645ed4514b8fa41deb9f99654d24987caf SHA512: a9da9b67a85ed396dae921afe0deef255853e487db250e50c7cfc0b43e8ff6f7b7f56f97cf77cd14d26a4e1c93daf5179bc7ecc203ffd55fb1bcc4de563967eb 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9332 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-dds_1.0.0~alpha.4-1_armhf.deb Size: 2218316 MD5sum: 157bd2ef973bd8573cad54b636643dd3 SHA1: 57b2bad9f9050838be2ede40ce2946463f6b8385 SHA256: 8d00746fc4380e51faf6b9f23932ce868d27d1bcad701f80ae7e67c212084cea SHA512: 57c0526f53ac0aa1544ec6a5ed2a968082462c8998cff29828e73b15b4d13908210c7245571a0dae86b3cb19cf597bc63eb6dc61041d17b58c9123da8672d5c0 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13504 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-mqtt_1.0.0~alpha.4-1_amd64.deb Size: 2841664 MD5sum: 51144f2ee1722dc7005f65c8d0c854d6 SHA1: 2306fd928155378c12b094ef1e4a2d29da6d5dfb SHA256: e5de1d4f6b58efd80fac9cdc6a09b68f44394cf79c5e33e50a451b491690329c SHA512: 2cfe27520fe0070655307e503f9111ba5ec68fe744796d120b6219eb6744763119013e9c8c5d3e5114fb01e1c79a312bbbfde411140cb660839ced35815d974a 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12192 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-mqtt_1.0.0~alpha.4-1_arm64.deb Size: 2531276 MD5sum: 4b48a900046ccf13b849fb2d2642daf0 SHA1: 31b4d8b6906204877f95be624b73730102ba29cb SHA256: eef318d262b046ab254477b177178592a741f1bc9c4782428b03dd4c23651b50 SHA512: 526d777583da1801d99739927adb1b5ee8263c5f4122cafeff00454334c28910957bb056acb534483f832b1d0bdd93dca3cf4f2221ad119e41bb14d4cfa1ab17 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12269 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-mqtt_1.0.0~alpha.4-1_armel.deb Size: 2612756 MD5sum: 4a4becadeb48aeaddddef764b9b9ac28 SHA1: 8703b23339bad518481ea44ccc0d8eb6579889e1 SHA256: b55cab82aa33a0172b07fe0d2a44982e51fa547450f38ab0caa1b93f93ae4fbb SHA512: c032d8225e3afa13bbf36c88dbefc2206300edccce1420ed022089ff0f5f9d6b1e5caf3ceecf7a6423610de33bc61e1377a308b5e7c60b7be6f6860c25325a14 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12184 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-mqtt_1.0.0~alpha.4-1_armhf.deb Size: 2656528 MD5sum: 8cefbd4192abf99412bceda2ff8a082a SHA1: 63b863e83a188423f1ac647fe28d17cc54df5916 SHA256: 36ebca3334e707df112ffaa3d278998828dcef89bde051d48b90dbe6b7ab1646 SHA512: 9c4c17dec83112e4f942e58197e88779d0533a0e9f8ae9e2cfe66e356a9d68e584e08541a1c67ad06049dce84e7ae07054dadeee717a7a38287add63e1774b01 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-rest Architecture: amd64 Version: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11601 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-rest_1.0.0~alpha.4-1_amd64.deb Size: 2209176 MD5sum: dbc2037f9cac5257ec9bfac399f9738d SHA1: 7bc6a19ae6d863a38ab7929226f057750a078354 SHA256: 119bd50e9b9cdda7a878f0f10e31352ff6f80dd792b0a48d4cb511170f0b7d8f SHA512: 43b0178297910cfa8020aa11fbca656fbcf824086246b7e6a42f32997a3a65253d25ae8584d9fdac37872f49112566a07802cd7f9ff6137630a8f0dee3a61372 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10411 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-rest_1.0.0~alpha.4-1_arm64.deb Size: 2002800 MD5sum: 66bb7641945b592456d1d8e297a3ffc8 SHA1: 90cfac270a19be83aaba41e4e541c64e2a3ffee3 SHA256: 0f14a554a9cbd856f21db20a9fea9c0eb7c5c22c69467cdba7ec3cd48af36ce3 SHA512: 19814c3e12788452624a97780e09a17222d6d5e66019e999238be0773ee6e2fc4262b3a232f4dd562eea2ee9d694821374a913c49a8ce29dc77e0d668822826a 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8582 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-rest_1.0.0~alpha.4-1_armel.deb Size: 1877008 MD5sum: 6864e372e98ae2e137ae0f5746fd0f3f SHA1: 80ac08d047f7d0fa30b938fdd6e95631f05cb999 SHA256: 3997e2e24053a810113d86c0ac6afee4b0963846748c2024e4bbef1efb7357c2 SHA512: 507adf6691fb7fd5e2339e47ef5e48f713046657e8b757c75858027b3d5d4915bca2395537230b4a59c4df1df3c60af9109babdf7483a956b0afde866548acad 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8460 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-rest_1.0.0~alpha.4-1_armhf.deb Size: 1864564 MD5sum: 347a845a54a5092f57a9b802770c09d2 SHA1: 3f4429137040896169fcd2f756a452d85d9ca458 SHA256: 5a2319be0f04ac2a24e8d34a2cce272a56d5eff6a57325a1d4cb64182f82ce66 SHA512: 5e9c27e885f16bddc98e25ab24af075226ca07bba7b2f06813984b628ee6085cf8cf5c74111b3ab120842712b63e45a2d7a7a6a3f24882da20d77f3695403a14 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15430 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-ros1_1.0.0~alpha.4-1_amd64.deb Size: 3208220 MD5sum: 5821a77f81812f52c3cc951cc65bcee7 SHA1: 8f2a8eacbe1e61b03ef8c53a454c02a5c0efb41c SHA256: d56723ccc6a35a2ffb8d105b9e5ae575a81b04028473e8a4829bff444eea241d SHA512: 09148d4d42cc3d821cf580563cca8b1ff597e4ae83835a121a1824da7ee2f21d9eaaac7528138da9662abde46734127e0110c4cc56c1ebc779e36a19a2c3bde3 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14088 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-ros1_1.0.0~alpha.4-1_arm64.deb Size: 2958096 MD5sum: 5551f361f6f2ae9385cdf748c2c728d0 SHA1: 5378e1c694df324f45012968d539a341b7c6ce5e SHA256: bc8d5bdf060dca99a9ac8ad6521c4f543e41db363a72514c34480d7ec06c3f13 SHA512: 33420424d6093f3e8e1cdf181a3736023c66886bfdd03009b1e9f96d965a681e79bd9d37acbf907b896ad30c21bf4eb28d849abd1e6229fcd2c52a79b227c375 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12299 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-ros1_1.0.0~alpha.4-1_armel.deb Size: 2856968 MD5sum: a5813c36fabc0b49d306001e64496351 SHA1: 317a118b3e9fa4b2be4be0db958fe5ea07815320 SHA256: e61272de1251c0096bddcab4a36bc1cd5cf9910aaaeff8dce154b73fbc46a6dc SHA512: 7a5c07b04ed2b116e71f9d8d1bf8f8d8fae2a721e3343f46fbc859948f94667ba178329c5f7683d03e5e5819ad3415445d7234f850aad2c5c1a149f4a8544723 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12079 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-ros1_1.0.0~alpha.4-1_armhf.deb Size: 2834328 MD5sum: 4fd978f8187732d704e357aa832d6bf2 SHA1: a550923be91d742849c52765f199b064880af018 SHA256: 1a3e18c1d384c580a676eaeaf7d68bac229cd9ab76032c22832cb2c88c522d07 SHA512: 46470e394035df26c91381d61feb6ce2638ac11c7fd4d86ba53ea6c990540bc5d9d72132ffedea2cc5e49d625f10890fcf927b0d478e6ebaa6b2df731fe8b87f 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13471 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-ros2dds_1.0.0~alpha.4-1_amd64.deb Size: 2710388 MD5sum: 5239d4dc7a00b13bc512c1cefee19b18 SHA1: b2377d0db79eca8c66478530559a574c47e05614 SHA256: 72434cb1347bde6bd84ceb741cc7bfafe343f697513c4cd3b55cdedfbb9cace7 SHA512: 6fafe7781d17bc705e832cc631e8da2ca5010f5f9aa7ecf6cc931b3477e5aea230b3c454e0ffde6d6912a2d5391e70298162a61b1619bf043348dedf81c44026 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12220 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-ros2dds_1.0.0~alpha.4-1_arm64.deb Size: 2474700 MD5sum: 2b8e91c701f5cba5ef33200f3286633e SHA1: f286a81daa3d0c53237d4ddc13815bf15b3f0b31 SHA256: a6cdcac099ea2a2a12b2645f59396d7b6f5d36f778cc8bcc03b54b7af697f17f SHA512: 3653edebd84b0ca8d5004807cb8f96694b7acc98f310ba9dc3ae3df64c00ee39f56f9324d595aec44cd4a02a281bb4c606cc881a312dbd6a42042342878bf725 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10304 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-ros2dds_1.0.0~alpha.4-1_armel.deb Size: 2340684 MD5sum: b0c42e9111148ad5318f380849c53c16 SHA1: bfbea12466fde28a5366b43ddc21644368d83cbf SHA256: cd252602440ff053177d4838c26d75c4d1afd753d6bf594d170c139062aa183a SHA512: 1a78cdaefef4e0d4f8e3c49c4988b48779f924f5ba081094e024b89862ed0c3d8a1000ac4170b4d80621d9a9bfa4fef610cea3d5b51187e62e1ad516e53f4e08 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9927 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-ros2dds_1.0.0~alpha.4-1_armhf.deb Size: 2349288 MD5sum: 6aae4f4586f88515c60895a74a53e104 SHA1: c46bca618360e95eda58e0eeaae0ad8df5e606f9 SHA256: d3f515dc898ae76ab5929cf7289002868f067303c601222859b55a9c39dc9f1a SHA512: d042de2fa259d29c4d159475efc83025560789be62a006a0d8a1bbefa9f9b7ffe6ad90f418a7aa8df77ec506d87430b59cd725b285dbbfd92aa7d0ab0f21de3a 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11955 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-storage-manager_1.0.0~alpha.4-1_amd64.deb Size: 2278696 MD5sum: 4dd94511a986dcd358bf825dcaf7a8a4 SHA1: b7c3d3c023870a65d66e37559a0fc267e392c502 SHA256: 6298654c1864adb65685f60988c402f747c2c76401d07b6ba3ae72918469408b SHA512: 9017c6db0679094e1ca111c303a75256fee847b5d60f402fabf5f9dfd43922a6b41773cb6b0b299d5e0ea4c92461893f4f575db7f64a3a2b2e9d243c399fce35 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10724 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-storage-manager_1.0.0~alpha.4-1_arm64.deb Size: 2065344 MD5sum: c91f1880260eb5233d3879288de1a11b SHA1: 6f9f37596b753e90b9476f63d538279282514b5b SHA256: 5c6f16919f806a3bf92bbb2f2f104e8736f61d2e294a0b6a243d2a2a670e04e0 SHA512: 7fd49329d5ad394df5c3423b761cd4d80cbdfe3c833cfa382088abbaa10faacb09bc4674eae1e3db205520d899d63f96976a72a46b5a808ef62c5c731b17320b 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8964 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-storage-manager_1.0.0~alpha.4-1_armel.deb Size: 1963708 MD5sum: 66635cb04b475b29b6ce2b1a41b0d482 SHA1: 0032d4665ae2f0fa232dd64f144f10e1f7059207 SHA256: b798fac434150aadf97dd441fbe406cc0fe4d1e492a939483e917949fc1a8f33 SHA512: 3de9d9346f9cbe8b9be73f194df3d4ef0364a25a4eb2632695067caaffe022532c09158238a0e3c6493b41d07cc4663f589b406d5df5b2d5406325b7d37d486f 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8835 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-storage-manager_1.0.0~alpha.4-1_armhf.deb Size: 1950476 MD5sum: aaddd71c1d29d28ab7fd88b1788ad5e3 SHA1: ebf3bcbffd0da4be28196277b9748a8e683fdcd9 SHA256: 2b6a5308ba9e7ccd06957ba4169c28bdcbf5dc1382d6ea766dc1a43bd703175c SHA512: 769c96bf86bc8276091a0fc4a9cacd6212625b65a3f51bc4e6e7a90b3e47a7e57760e806c447920a225388a36d28654adb714fa270e71b90854ba011c56546e1 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14065 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-webserver_1.0.0~alpha.4-1_amd64.deb Size: 2659392 MD5sum: 790f6a05b928437049a4c763982f9f7a SHA1: 6935078e499ff7c1b45b7bdf53cf47f40a9956a7 SHA256: d42cf511669b692277032f68d255021f5f02531caa0e3d01c857e6c671e34194 SHA512: d6af4ee1b547546b1fe9bdc04453f37db2675a4e16556c297ad7a219dfcd4eff380af2972c8a6732ceb7825a42c42e7438f9ca7e7632f4991cdd804f2f850ffe 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13157 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-webserver_1.0.0~alpha.4-1_arm64.deb Size: 2453656 MD5sum: 3ba5bd5a516903385372d047f3b3589d SHA1: 6db88fb2dde514c0be1a19c9eacb4b982ef852c2 SHA256: e1763b9b30fcbc03942bfcd29a3175c3e28e23a3fcf205c0c3bfa6b18728a07b SHA512: f3bb963436e6afb1b87feda95967a9c5870cbe060b621a686f38cd3ac80eb1cb5ff1b7e94f9191c62ade74b226418b736dd84c4b5ff99b1813997bfb6a2cb330 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10848 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-webserver_1.0.0~alpha.4-1_armel.deb Size: 2247664 MD5sum: 8f82f7213f07718889ea24fa8393f99d SHA1: 0da696e54d881e30424de8dc44c66404ef60464b SHA256: 49a5c180001fa23c3f71a5d0a1c44be6509e7944afd36750c18d96123e3e9c37 SHA512: e65a5ed8fd1cc9c81f9e311d00aa20203a2a979bce69e3fee5dc5e5db9134c7a5629c2e372c3767a9296ab49d0b52b8aa856cbbb4d4534a0eb4579c7dd8dd836 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10699 Depends: zenohd (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh-plugin-webserver_1.0.0~alpha.4-1_armhf.deb Size: 2230576 MD5sum: e27affb45509ba43bd550104aa3df175 SHA1: 545d4f5fc30206fae96cce1adff31eaf954c13d1 SHA256: 334c9f77358e96f5f00cbf5a24a3f8b4f64c492ce29165d75827a6010a25bd99 SHA512: d54deb2cd45db8ee055d178214df3e9bcff1205339f9e5c0cf17f24d22ecbdbd475e6d9156e8f26e92c499eab6890f8bab841469004b084bee4993e4f9e558be 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~alpha.4-1), zenoh-plugin-rest (=1.0.0~alpha.4-1), zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh_1.0.0~alpha.4-1_amd64.deb Size: 17296 MD5sum: 6cb0dabf4429464a35ea51b8b4d9fa58 SHA1: 28e57a04a5c21a23d8d81164a5eece5aed8c41bd SHA256: 2b8ba3c911701836ecfe03f17cfa75ddaac66cd4d4aaa65e7c2609aed19cd034 SHA512: a5f640361073f9b527b26de0f6a32d9d9c69f661354fc4d2c2f6a0e0c75a4bbe2b01500e4e9f594156dac7e470b3a4df2a032242f44eeea47100398f3f35d5e3 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.4-1), zenohd (=1.0.0~alpha.4-1), zenoh-plugin-rest (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh_1.0.0~alpha.4-1_arm64.deb Size: 17308 MD5sum: 9d1f4c764ad404ed7b30836ac7312160 SHA1: 9ce5910d0e14af9f8daaf84ec9ccc8834deebea6 SHA256: cec5e15cd91ac5112aa8917058e489f2f8cab8979a0296338c8973d799ae2d34 SHA512: a268012bea2c13d412540b4c0123c631437f7537964898861c1b008954bce6ba0bfc146491670a2cab5a7dfdb2c8f98d0c690731e70649642668e9b8b771de56 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~alpha.4-1), zenoh-plugin-rest (=1.0.0~alpha.4-1), zenoh-plugin-storage-manager (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh_1.0.0~alpha.4-1_armel.deb Size: 17296 MD5sum: 23cee751fd9584bf215dbb8f042f51cb SHA1: 03d05ea9692b95ef4c48e51aa48799b82a995e0e SHA256: 1ca48127d6f333a3b93ea8fe3ce9f48028a6d3614e716be11bfad261a0e188ce SHA512: 8e41d53b313036f5b1967572c3b71e256e215cd14680394453d8d658be6e45e253b72b226b2be6e2932ccd543e0cf1482b5b0772fbf22403d74f555e89e5433f 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~alpha.4-1), zenoh-plugin-storage-manager (=1.0.0~alpha.4-1), zenoh-plugin-rest (=1.0.0~alpha.4-1) Filename: ./1.0.0-alpha.4/zenoh_1.0.0~alpha.4-1_armhf.deb Size: 17292 MD5sum: 57a22f31878dd7134c251975ac43fd1c SHA1: a00968372c6a2aa7d88b3a71dd985af64f31dbd7 SHA256: 6e66ff9a46d9ef6c6d1e5575799e9d8e568d3ac8155ae7954a51f58b3c5ec4ae SHA512: b657c1bd2a961ab0fed337458ca28d7ad3822f21d1e4a10074d679282d2def69b1dee44d2d17d5ca9c10d2c1f8dcd6a401353e5db5bbf49d8ea0afa15dbc0cf0 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18355 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.4/zenohd_1.0.0~alpha.4-1_amd64.deb Size: 4482076 MD5sum: 02c1623eb58fce705186ad93eb6ad77b SHA1: 2ff8806122183804593d7d125fe726274f57838d SHA256: 54009376f2d40e407f672374517c26a98a68f47a83ce6329eb17b9b2a9755707 SHA512: cfdcb4912007a6e1329d9d253f24b569ad7c186f8feafe8ca01a2684e24470dcfc03fcfec1b431363cc8335fb740a0fff0c4bbe7ed6593bf00502f19a3e9b957 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16294 Depends: Filename: ./1.0.0-alpha.4/zenohd_1.0.0~alpha.4-1_arm64.deb Size: 4008400 MD5sum: c84badbe5bca1599b378671bffaf91e0 SHA1: 341bd9128dbd07b097546fcfc540faa40c8fa09a SHA256: c84e2f5fbcccc3a2d5ae8fce0e45ab449aec3f4e530f6b62d841ac3a74b78031 SHA512: 929ae681baddad08518f2fbf5bd2c90f7b878dbc74250b689eece8e1c0bd4502bcf2f20da9b522d7df42698ae9c590dc738ecff4d6dbc300b2c2e5a974f4e497 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17730 Depends: Filename: ./1.0.0-alpha.4/zenohd_1.0.0~alpha.4-1_armel.deb Size: 4360520 MD5sum: e1e79e185100cc05e3de9c63c76d480d SHA1: 127aeac7580eb82fab64ff5bca58020c78056298 SHA256: 82bf313480504a1cd56d3a190f80f1ced7ece6ae47c4b51407cdc7eb78373b38 SHA512: 8748800208b287de938646c3ead39c0ec50ebb1dd1c9678faac7e38ba6bdc913ac36d3d1159417a720f159010441b71341b1b20336ef11e79e48a15db1c7dad6 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17501 Depends: Filename: ./1.0.0-alpha.4/zenohd_1.0.0~alpha.4-1_armhf.deb Size: 4413508 MD5sum: 2ccd00480050b68f6ed69983b53acfd4 SHA1: 80ddaf2637f2b507b55052613b83ab9e6bf55d38 SHA256: 0692ccefde15609ff6fbad31e941661b98d26d171f7a84512a4e3373e9f46472 SHA512: 5f911754f425682691f5b3d4bf2bce10784b7ab56b7c195a0de1ca945597097947c07022866ff79ef114523bf54201f3f596213e43f5046fee636cfc28606608 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21018 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-filesystem_1.0.0~alpha.5-1_amd64.deb Size: 4650172 MD5sum: c87a4b2c154c80005a6700a0853dd72f SHA1: aa407d6d5ac74f67f2b5f315616a206faa95b6d0 SHA256: 73444fe31b652367a8c206b8bf582fc68fede6b04146b318d87752f638b0e86e SHA512: 2c139f17f4171dfc9b3e4a8d8c7b1dbca1fdfca7757cfb6206d129e6178c146b62ffd606296819f14fb5ec6fba5996e019bb746cbd4ab886237437453c8e9b4f 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19161 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-filesystem_1.0.0~alpha.5-1_arm64.deb Size: 4185708 MD5sum: 9f45e545484ebaca71894a706854660e SHA1: 0766507420d8e057fea12046df6a243bf7b64405 SHA256: 3a3707fc664ab99eafe429ebe0b5f522b0506df48905b0b6e9cba8103c8d187e SHA512: f3298ab9e2c7e4cd7a8315830918c69bcb78d28c18730585d1bbad3498fd1c929516e0f9e708cf54acba97ea8acb0e66bcf49f24f8a1c2597cb34487fdae983e 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16752 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-filesystem_1.0.0~alpha.5-1_armel.deb Size: 3964292 MD5sum: be761932c7e5eb199e16340746974e23 SHA1: d0607a20fbad36a111122f6c2b31e168f71b2a8b SHA256: c4b21d1326ec8b7901b0c9f6dd19fc4ba610f4b2c60b69a0e099217c88b82f62 SHA512: b157f155c3a4c956d2e6524ee4168984d4e05393aea6cb705b37b1c13aff8abfcb7efaf0e6a0be577dbdedd90d1267d974b20be49e4f718f69305b6c381a7946 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14866 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-filesystem_1.0.0~alpha.5-1_armhf.deb Size: 4060316 MD5sum: 8d7ce17b69d2d66f7a2206b0250b929b SHA1: 29ca7bfadda544d3c0afe42555be2c74ced3a2a2 SHA256: 70e3a7aedf21cdc23e11da5d960b3f3585994e6df775c5768eb5f1af3c252fee SHA512: d57730151b5d359ec1eb9b5f2f7c3e733823d10e588f75f936e42cdd74958291dd2ecc5e2d050b8c718481f087f6d611e29819717cdcdcf8869f425daa4483e7 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15725 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-influxdb-v1_1.0.0~alpha.5-1_amd64.deb Size: 3124360 MD5sum: 4d3a9f76bffac9d943445f9b91ec5abd SHA1: 1d14e2de7ec41ba161c6825b72aca7889691cce2 SHA256: 6c26cb737999cbe8117018cf86122f3a2ad258c32e97646f5d4d9552b3e19f4c SHA512: b5334668f4082f0ccae006a592b19373ae9f5211f63a73ec752621da2c8cc8ffd3ed66b08ab9441b8d9f90220135be641f9b8d70caa6d8f55806d1cd271f1438 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14121 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-influxdb-v1_1.0.0~alpha.5-1_arm64.deb Size: 2814660 MD5sum: 1a06cf542d4d0a710e5b23adf98d45ef SHA1: 74bc2176259250c563131fbb42b65298d7702955 SHA256: f2e4022b897608fa43bcd69b41e8d985d19401b0c469c672a7dbf3af51d5729e SHA512: d7b380dd6f1193ab98d7dea3c699e8d5f7ba7847bfd5ac9ad67576b25f6a34143a3aca2b54825e09bcf501c2e553f15e40b848f1e1557c9b84fc1bc6214e5a2e 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11940 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-influxdb-v1_1.0.0~alpha.5-1_armel.deb Size: 2566968 MD5sum: 48e438f9700d77c494ec95d20e8f21fb SHA1: d14fc4a20e96c3ff3b8b26e9be30261f7522188f SHA256: 18b56da9b8bf51cd349c548f62ccb3eef9f4b319c6410020bd4d2007de11c5bb SHA512: 4d7c3a44181f9d91b2c0f427f3a620eb3407e29927cc1e39f4a933ca3ca6994a8a3d632eb8c20b8c7642568610e1f8d957fe21f4394f3a0de2486fbe03b20944 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11804 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-influxdb-v1_1.0.0~alpha.5-1_armhf.deb Size: 2557572 MD5sum: aff1f09f2adcd61ed3d8144a58b67c79 SHA1: 853b941f22df4d20d1cf5e3773d91d8750aed960 SHA256: ceed79de56829e10817d8f193220bdb554778e2e2bd93603aee45cefd4d3c931 SHA512: df43e545a5b34dd8d2a4bcb4c599fdbb7cae6d1cc9ed7ae8245809700e240087ad54d85e938caf279589918dd6d94f55bdd9ff8de2f9234aec9bf502bf764ec5 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17482 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-influxdb-v2_1.0.0~alpha.5-1_amd64.deb Size: 3847744 MD5sum: 97a49974f84f7b73478b238146351743 SHA1: 27543b1592285ce318281addd608b3ab32e88b91 SHA256: d4294d76897ac75ae6c67047876d4a23fd83ca649e1b86d0d4c0c2d7b4c9f533 SHA512: 837278d2ab844ae475d563c1e23332a423c96743399b0dd687512b2b21b8c831cfd6b5fb25e4add99687d4c74100dc0a5a3d8e18265e1f3f1a0ddeaaf95797fd 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16503 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-influxdb-v2_1.0.0~alpha.5-1_arm64.deb Size: 3529816 MD5sum: 5a68e03392c103f10a3cd840bdb05544 SHA1: 841a7f99d95214503802559318cdceb1bd1b32d6 SHA256: 15c6749b810e4727645233147af480183598d3916f938b29047f34a30646cbee SHA512: 4bbc85c0eb27092f95058629e7a4a34c47555d0e362f6fb1c2e0bfa8981de6e02e3569a65571058dcc2537543aeaedf3efdd738b6286e6ada106a7168748086b 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15817 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-influxdb-v2_1.0.0~alpha.5-1_armel.deb Size: 3511632 MD5sum: aa770689fa05ffe31bedaa3644f6a1d2 SHA1: 090d08a3c19a17bb6ccced069916bc4a667272c1 SHA256: d6b86a912f7bdfe035ef025a0d21b2cd6a63f88af21050504cb8c0661fe98b9f SHA512: 02e168009ecdde4be101d815813eda856ca0aa370caf6ece4fbdf39d1b2d82091b01d60ba998ee567952fec5044462210a87f6fed3ca23638a5de975594ba3b3 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15699 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-influxdb-v2_1.0.0~alpha.5-1_armhf.deb Size: 3554608 MD5sum: 9e7a061cb0413da71258d089ebe3cf87 SHA1: ee8340abc31dca49e885401ad8e98f6627ce03fd SHA256: 1d5bed86b071364ed2451cbd6925852528a112493583d7abfa096aff64a3d91f SHA512: 5830c200133245e7d4f1b0950b57902945bdda0019fb0b65f14662e2c0df750c027426b465d69014f29e3432c2ba6cad6c949f9b54a2c567967ba3604af232eb 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20638 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-rocksdb_1.0.0~alpha.5-1_amd64.deb Size: 4598756 MD5sum: 59cf76de684918ffc73f6c227e80610f SHA1: d3ffd8d84d3c4d624a7bae78b468920651b1d408 SHA256: 507288258f8ed12a63a115adf8cafda0b031a2c1ec0212a01bb2f7338d10b52c SHA512: 021e33117be72963100133bc385a450d97126262e4f61ed87b69ed6b47b547cd550e65c9505a3e3e5432e3f3fa102b9768983f6ffd2dff0af4c3007d30ebfa65 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18670 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-rocksdb_1.0.0~alpha.5-1_arm64.deb Size: 4120700 MD5sum: 88d371a063173ea2b3578c46768a78c4 SHA1: 1e47d3112cbac79396e95df973e26cefb327b46a SHA256: c4bd9c3120948211dca48de95eac574d86da5bbf2ffe85de87a2496d7fd74da9 SHA512: d958a706051c31e491e68b2a4a62a5fec11c925fea4b1ee0b1c5d0977150222b72dc4ccdf1a72dc3609090439c6efc6410be3aae2e61fbe4be8891f2bc8d691b 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16401 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-rocksdb_1.0.0~alpha.5-1_armel.deb Size: 3918088 MD5sum: 9de4bcf3363fb852c196af9c1b7f1caa SHA1: cec68040d40e1888d6f5a7f80d2ce0a965e1418e SHA256: 756ae4db766dcae28b7e2c02a371479723a2e460906b6e827085de6d9da6fa65 SHA512: aa5295dfeae75ff1b8829fc922de68981ef249dadf32fdad29595fadf963b10072a1bb7ab1fb934730aaa8eaeef20c70684335b5ae6c3d09f6763d17c414f2c5 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14469 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-rocksdb_1.0.0~alpha.5-1_armhf.deb Size: 4012040 MD5sum: 61e87565a377f58bca67d178c32d8da2 SHA1: f3ea3dde785a2197b75742581d9ccff3d5e3912c SHA256: 08dffaaab967fe65dce0e5c20a350b9d09a083f9614a888dca76fb40ab297334 SHA512: 4c9b400569038524370423b93fce220cc5030d214ec65814735010620e04757771299df73d6677a30c5dc4edc3f57f77191dd27d2333e62bd8d9693ea3cca384 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27304 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-s3_1.0.0~alpha.5-1_amd64.deb Size: 5516900 MD5sum: 4e4128c6b58b8b6b270c0732db7cd09d SHA1: 4a9831840f52963520032622897d67bab9567bb0 SHA256: d2d529ff421062f6d8ba0f8b02cf414ddb47ad2fd885d5019343a8fc5a18e852 SHA512: dbb69a913e395f489f0c6ff951d152c631ea8ae4ec22d268039c901c156bf4a24c1f0bafd63edd1162cca9656d6a0c8fb7826d3fda8c96546a0a88213df59e15 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26545 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-s3_1.0.0~alpha.5-1_arm64.deb Size: 5234804 MD5sum: 9f9f0117f37e947134f209952dd186a3 SHA1: 36114ad983c72c1c0c1c1968aa00842d2cec6c47 SHA256: 961ebdd3f72f2fe0a9992aef7fbb5e68b3e0fb5be30793e32b3683b7fd932bcf SHA512: 00f1f40f461d01e2058a7282233ebf6840a54a70307e8fd666eb21c84a9e9e300dddd963cb34843a67aaa2a627bda5daa1e808deead3dabfdc209bed4ddb24c3 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25336 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-s3_1.0.0~alpha.5-1_armel.deb Size: 5101660 MD5sum: a7c2b925245277211e1a16a1cd022ff3 SHA1: 200c0d30d037767bf898cca4f9d3bd66f376472d SHA256: c9510980b3ffae4f41c479b7cd5a124dd8000b03141e0ee2364ae5222e0f403c SHA512: fec5dd7a0cd7e30cdf9c9cec7310ef773f007242e57277f43181de6554ce901c5450a7dedf247ca7d80640c400ba47709c7fcf65c2adb77f0c29bbd612d13a4a 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25124 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-backend-s3_1.0.0~alpha.5-1_armhf.deb Size: 5139324 MD5sum: 6032c2adcc2f36ef30c3202e3b887f5d SHA1: a5d21b80e8848cd44b367fe3578893a3613890d9 SHA256: 44de92e464a454c3d531a2aabbfd3c099d0f02344c2dcd75f32b57dbf88b3366 SHA512: 836ea7c3101a7bb1f149eb484513db7136547d4ac2b4786b83787eb4d3fbc810186a5a7341784f574f2033c846904c885d24a241b6a612b28d24f9b83caf91b4 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20697 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.5/zenoh-bridge-dds_1.0.0~alpha.5-1_amd64.deb Size: 5203488 MD5sum: b9cf51c26a6b96f96c58b7d9d77a80c5 SHA1: cafd1f5047e4f1d912e94b58e6984dda7ece35d4 SHA256: 8c3b3693ef737b81f9f0ccefee47a68253ef9346c4bd8700241fbf2386758215 SHA512: 4aa0c99ab06fe69971ad2c13a9bd4175a3de01392a945721ec1bbc9892b4278eb73ebddbb552ff0bd985939f801f8c57ba28e3bd1466a9f18e8ea19ac0561eee 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18793 Depends: Filename: ./1.0.0-alpha.5/zenoh-bridge-dds_1.0.0~alpha.5-1_arm64.deb Size: 4684416 MD5sum: 00a9256ff9cfd1232670df1d2e3835e5 SHA1: 2e87c4ef2be9c87e88441700be32b8265bf267b7 SHA256: e801b29a5b46b2881b7ef501e5c8ac5d418fd95565dee4a14f6b2522fbe96b64 SHA512: 189f34b2d79e031ad1b076b75f34bcca74b13da13a990acb32e8027f751ef7060325fcfa00020ea1fd81ede0d363889b98e5667d217ebd6dbfc0d7fd05ee51fe 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20048 Depends: Filename: ./1.0.0-alpha.5/zenoh-bridge-dds_1.0.0~alpha.5-1_armel.deb Size: 4980172 MD5sum: 3b3cd8eb9df64f70ec1a3685885ef284 SHA1: c79b1ecb01c5c4ceb9f3da29f68bfcd04d23438d SHA256: fa6d22a97d3d72b934e2b1d5209feabb9d83038df19f205caae7ca8ed8b37093 SHA512: cf81eb36cb491a7fa6f71204c78e5328d348ba6d240486724037fff6b9376e5b75a5b66679c0935f74af544276f327399ed7eb85c87f2cd47d13b88c88b4877b 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19562 Depends: Filename: ./1.0.0-alpha.5/zenoh-bridge-dds_1.0.0~alpha.5-1_armhf.deb Size: 5025264 MD5sum: 4176ae6baf50993daa2ff61b7b9fb604 SHA1: 9b7f133bd6dea46848e25d660d0ef4746748fa3f SHA256: bd91c3816834f814845e3f50d7d4a3a267470d1a1ed057b4ca069d4989a4ba01 SHA512: 073213050d2cf101a9ff9807442df0fc32727d90e5b235909a08a274df91bfc6f55df44b9a0d1b696a35d045ffe987da4a244cbfb2f91d2174733e8dee555b7b 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20551 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.5/zenoh-bridge-mqtt_1.0.0~alpha.5-1_amd64.deb Size: 4984196 MD5sum: 32db63c1a0c506999535edc4abbfd9f0 SHA1: 05cb3c04f0090cf3266f0d10e101096e6f8d0bd8 SHA256: 4cb8503386b995ad2f4dfc73181a5e77fa93ddb0bd5c1c463bde741300616774 SHA512: 51d17d02fe4649cd6b72a15dbe067b67ecfc273f3692ffdf6ffd2ad80f034d896e0ca0e69390d14b215879bdb947d3463778cb826f25122f7d43aa7f0ffc6a1c 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18617 Depends: Filename: ./1.0.0-alpha.5/zenoh-bridge-mqtt_1.0.0~alpha.5-1_arm64.deb Size: 4490272 MD5sum: 2d29dcb7ff153a4ff2c897f29b8952d9 SHA1: b679a2019faafc835f9ece1039e6e9dd2b5bb2e4 SHA256: 8b62be4bb45cb4c9f82893dd9dd82bd1c2103619f4352e0913853f20ea9d818e SHA512: 9e3c612a421a3351730dfbfe423a58d106c58a64592327a90375df130188a1c0875b769dc6bf785d2ded1b47744ae319b3cb1cff1f52f95f328f2858efbe5650 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20040 Depends: Filename: ./1.0.0-alpha.5/zenoh-bridge-mqtt_1.0.0~alpha.5-1_armel.deb Size: 4788812 MD5sum: ff80508181d03a977e720b01ed3af0da SHA1: 9379959b055349e26e49d362abdf8a15e509190b SHA256: 537ae057485c98bee45569711e6bf57331c44e8f6d1338f4455fb1cdd17d4c29 SHA512: 53579bfea88a99ea6299aa4216059f6f0c799ea96c49ff496b17a01e714c7412199f6a45a281d444124e3bbc988245e6d7952eb9a1bd5bcdf73566cb3cb80994 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19768 Depends: Filename: ./1.0.0-alpha.5/zenoh-bridge-mqtt_1.0.0~alpha.5-1_armhf.deb Size: 4818628 MD5sum: 2858bfa57918f33d08909c2a020b2c6c SHA1: 67e8e8f6cb182282e1ea5b108c3ed18c9324a52e SHA256: 53542e26bb87d909461b7e306e3b445c721dee6062e68ef8ad434f292da42770 SHA512: 854a821ac87cbbc635cc9224d90a5c7e1ba07fd286add2f90269adcb23bbb1743f13e01dce0e699718d73b5b4922dbda58cc7f298bcd1d13c6f86e7ffa5559e4 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21985 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.5/zenoh-bridge-ros1_1.0.0~alpha.5-1_amd64.deb Size: 5367036 MD5sum: b89c0e4a0b5e73f1530b8c2091b9ff1b SHA1: 3e3d165e3fb5422eda72af40ab2fda37ecbdb9f3 SHA256: 9fd97baec0b6eb66f9be887a00dddf5cf1e8000703b0cce29bb0aae41104740d SHA512: 089c51a10a947aa83263adbbe3c5572bfb9f484600e6952f4304fb085d5b5397900f1f89ec4b2e1796223033d3f7b1d6835c5f5175fa475991333e942e803ead 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19981 Depends: Filename: ./1.0.0-alpha.5/zenoh-bridge-ros1_1.0.0~alpha.5-1_arm64.deb Size: 4842168 MD5sum: 941a3fdd867fae60fb1ae52a19262c8d SHA1: 749fca7633f34e3e1bed2cc8c2704d3dc9f4676b SHA256: 87e34dad6fb2f10c7a9fd810fbde720bb1ae94d9f51d3afba18029c21892e048 SHA512: 3cf2a256fee32b5971ff30bcf2745b35af10e6e2c6036f12ac0d00d6ca822ce7432b90d45f65ce7f557de3e886311c6134d3f2d7eee2164889f4c93542fe0c1b 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21384 Depends: Filename: ./1.0.0-alpha.5/zenoh-bridge-ros1_1.0.0~alpha.5-1_armel.deb Size: 5169732 MD5sum: ddb4c3f73e3149de8dc5b1c720329654 SHA1: 42f42ae829d38d177b605a1b07da3c13e5ce5ecc SHA256: 66ba23037aca12672e4135f6d9ac808e74ed742e0a9b9ec184f4f511c4f9fa44 SHA512: b28be5c499cb5d477fad8431c1533fff6626744737cb2df079fb56ea6f94beb38bc59dd5188c73f8c694b7a7a041568fe53c5d782e111f882e442942215f6223 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21082 Depends: Filename: ./1.0.0-alpha.5/zenoh-bridge-ros1_1.0.0~alpha.5-1_armhf.deb Size: 5199232 MD5sum: 6273d93ac72cedad630d6199bfb9d739 SHA1: 19241273bc11b34938f33b3b72b58f48fd5b47e6 SHA256: 7d099be40d960fd252fdc95aead9c21e33cbc7cef5229aa1ae63ffe32d7b9c49 SHA512: 9288d9c5718eb2822f38f67c66609bc2c9552047c232b8ded5bdb1fc40f39e87dc427689073c1a6b842fc48fc6efc239962a62c08f68ea6d48dbdebd68a98fcf 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21323 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.5/zenoh-bridge-ros2dds_1.0.0~alpha.5-1_amd64.deb Size: 5323728 MD5sum: 21d8b07abe3c88259c03b44fc782a811 SHA1: e6c8f1f01554541efc427f632702cc15aa8ffc5e SHA256: 03c9ebb0ed2f6e40df5d2fb1ed5038d80db47fdffc54a22bb92f196c931cac0b SHA512: 5f5610289c896f96ad935e24598360cc0c0b1443a06550e94f8ec28f8e15606dce3de4042a35b7e354d29ac479da4673ebd5547ec9bee20bac01afb22464efc0 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19385 Depends: Filename: ./1.0.0-alpha.5/zenoh-bridge-ros2dds_1.0.0~alpha.5-1_arm64.deb Size: 4815968 MD5sum: b7787664de64d51e317d794f32aeb509 SHA1: 91e40a53099ac6051abfde321a7d55e095379782 SHA256: 4c26be5624fdb563febe15bb0e26324977a98eb642aee3e3b037bb4ef4d05da5 SHA512: 1495af8472c99b8a8fc24be83d0c18545fee85d647173791f0ae1cab11e3aa3307b404911ccbe73f23dab12fd3d4832c5ec0267e1177e455680497203092fe86 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20648 Depends: Filename: ./1.0.0-alpha.5/zenoh-bridge-ros2dds_1.0.0~alpha.5-1_armel.deb Size: 5098108 MD5sum: 1368b9a68ff5cc68f81bc16e5bac58fc SHA1: dc1caf6dc897e8529b3104551a9c516f43792213 SHA256: 856f7a8d046d741a4edb566c371a342308faa79dde7bec170d957d4787334882 SHA512: e3ba1e86c573d4c89df156463e7acf2bc9a1399ca0f4e2eef3ac8c0cd34e44adc7de487a72c123a9bf88df27f000316748c379c89b2013120cf633a56b6006d2 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20152 Depends: Filename: ./1.0.0-alpha.5/zenoh-bridge-ros2dds_1.0.0~alpha.5-1_armhf.deb Size: 5155460 MD5sum: 5e83cb115e99a2881be68da4b284576d SHA1: 00cb9f71c7dcfcfc752b631dd625e5611e7f27b6 SHA256: 2a16adf6e5e737592e64b901c9b5378c685c480e4a17d171c07684d235471596 SHA512: 9490f7a791ad7bfcc3e9f8e425b3081974000fb5d847c935d5259afa63dfb9540c3f298054492a91859418712233c4c1de5ece6f465022ce7dbe0fe9a386fe9f 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12836 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-dds_1.0.0~alpha.5-1_amd64.deb Size: 2588304 MD5sum: 465d5aca0c118d674722f8911d182b11 SHA1: dd2c53e6424cfaf3d1d416a6a816538b88d341fb SHA256: 7d81fd433107049cbeb47222ad959bbff0d12f1d4abba5774401f740094cd12b SHA512: 2b0d449237d8d32fbd9198fb43d34feceb426df72bb77893421117c706fe8fb44014b93c3cd61d461d92a89fad9226ca834802a8888aefd1930de5af1256ecf0 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 described 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 maintaining 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 architecture 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 embedded 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. - **`--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 information is 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11630 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-dds_1.0.0~alpha.5-1_arm64.deb Size: 2357368 MD5sum: 7c8b2574b1f3f41bcbdc288f766b1d64 SHA1: 7de9d1d4730cd420349e9994ee04da5e7923fca2 SHA256: a4bf5bd5e3d18192773b22a5e6d4f2eb35f17c6e94a59260642014123dd8595e SHA512: 4914114babd53cac7095307f6da38e4981cd656bdc4e81d6d203f8ebb0d4a2edb15e5d1ebff1139b4aaea8e91c1f353d0e5545512282025c4c6f7ddb6875deec 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 described 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 maintaining 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 architecture 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 embedded 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. - **`--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 information is 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9703 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-dds_1.0.0~alpha.5-1_armel.deb Size: 2213876 MD5sum: 5f2edbced153c597dd12f5e24716c404 SHA1: 178ce97913454d4dec324a7a4e3058b2769597df SHA256: 4e81ed17f659cc28197cebf85965a27daf81fa2834c5d361a222efcb64e4d98d SHA512: 48972e94dde69f2d66de87181b3c4afa641f0d83d8480f08c1584284b2aedf0b9d61b40d6f414408f49bf6faf5971a92e1dcc9a6595d33171d118ee6e95d2a33 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 described 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 maintaining 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 architecture 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 embedded 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. - **`--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 information is 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9334 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-dds_1.0.0~alpha.5-1_armhf.deb Size: 2217980 MD5sum: dc5cc45a2d6888107db3098903b2ef40 SHA1: 07d09ef64863bebf7c0c342a5cdeb1f6a62656de SHA256: 12fabf860ae52a4dc3ed9303f71e921031351b8f81edaa56ca35e5bfb6ba11c0 SHA512: d618b836fcdbe7ebf0a768dec6a31fb2c882f80b5a7034aca902d419cbe95ba26a47dd87680a3dfc94054347904ee223c2d9b195f8220985b73217ddf775a094 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 described 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 maintaining 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 architecture 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 embedded 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. - **`--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 information is 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13504 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-mqtt_1.0.0~alpha.5-1_amd64.deb Size: 2841180 MD5sum: 2556d7e60da3fc71a51881b6ac2abccf SHA1: 8667d95a29a378bd84c9db4aedccde6a7ac4b5bc SHA256: 17ca69d7b7c4b3391a6812350ae6c44332dffd4e8d3c3d0e4c79c2cf7d24912d SHA512: 9c2eecf5af3ab45568c6c8f4d864c7d93f4773660d0ca01e6dc1b03e4eab65eb248ab334c0dd3e4933ed43b91d783d72b3eb9832f0adfd56433f1c50f47cbf62 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12197 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-mqtt_1.0.0~alpha.5-1_arm64.deb Size: 2531700 MD5sum: 4b784044597f05c5e59e5bb81dbf766d SHA1: 109af0084590d3f58f52907e94304f28cc9e2ddd SHA256: ad4fc3e73a7c006c37749031a00b66bf88d78cbf8f0bd126645317d7a5f4778c SHA512: c780eb79e5ed9160f4dd7e287dbd1527403b5166d1b6a4d9e7087c999e9d6018ebb6168be3e87cde60bcf738df6e3c9e2279f9383f619c506cc4cf9bf4a36361 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12270 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-mqtt_1.0.0~alpha.5-1_armel.deb Size: 2612556 MD5sum: a2f18965149fbbcef6464d3fd717302f SHA1: ba3c8fc6f7ba5b498f6bedc84e788c9bef5255a4 SHA256: dd925c1259cb8bcb0348d6ee8d0edf94975f31ddcc5a34164888c1b2ce399714 SHA512: 228aa5462616c190aedcf3303cc368f1a4ac642c48be765419b2ebf732be03251b58c159d66a7649fc341d5183e04e091100862f7fb2772afa942dec9384393b 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12185 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-mqtt_1.0.0~alpha.5-1_armhf.deb Size: 2656184 MD5sum: a0c60fa5a43da5d3d11983de6013b6aa SHA1: c8f8cc5b8f33ca56bf3a2a260ca3248dacee1c10 SHA256: aa203963aa4c255a23516e10964ef0da2e366ef800f0c0c263e7b2a12fb9fcc9 SHA512: f422f3fedb71bde8f2b41f69835103d0e771a745cd319154a9235a5d4fec7bd6ca47697f38f5d796314dc6e75ba14e8463795ab73577c40a633e19ef0c38f150 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-rest Architecture: amd64 Version: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11597 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-rest_1.0.0~alpha.5-1_amd64.deb Size: 2208584 MD5sum: d769213958c7ae845d007dba1c9bbe50 SHA1: 55fd0167bf982223cecfb392686109f07022e2ac SHA256: 79445104c88ae7b86e79ee0c6765f988b2e679ba44293370875852212553be48 SHA512: 62040a8574efd3a364feb59f2768137f910c6459436e1634e46a99735875d31c639895e8a3ef92aecca61b8f8656997b81aa70144bdb0833ef29227311655fe0 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10400 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-rest_1.0.0~alpha.5-1_arm64.deb Size: 2003732 MD5sum: 268cb9fd8de1ee07e45fb31dc6b16763 SHA1: ad7d8c6cae1c172cfd00b8e1cfc11089871e1584 SHA256: 2cd914005b3b1deec2fab981d311e097f824942ff2ab358e9f78c1a0d8097fc9 SHA512: eb87bd6731c9c383b708b87dfc29a8dd6346c5344994499b9f017457a970f8e7cfa465f504f5fba7fd50d2330c455a0aa072ec29cbb44c3b827836dddc6fe93a 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8582 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-rest_1.0.0~alpha.5-1_armel.deb Size: 1876764 MD5sum: 47dae01c89c5230ad39ee711bd6d745f SHA1: 3b05e015552da09d530786203eb51f72d7e717e2 SHA256: 22ed8c7bc61d0b75650c8c5034bd6c5bcf2d79e8cae41bb31fce60103805d5b0 SHA512: d4ae7b5360d76cf80ab8a7ec765c359330cb95b8991fd5b75009ee941ff6441c3908c0c559473b0f0df2e5f349aaddb597aa8a5914661021e35d5f2b18ac602d 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8461 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-rest_1.0.0~alpha.5-1_armhf.deb Size: 1863972 MD5sum: 8f03a94171d9d9edce1338b0220e2a16 SHA1: dfa07127cf1ed8b724698706ca648bee7313ae3a SHA256: b406a3d398e17db556fdebe40dbf4f7f12dc073d034f09c1ae9d3f6251b02316 SHA512: 28e61d196b98e872214e21682418a153b643cdf8158b8ae8a9ef0b276cc9f8478d9ede9220e676fe9bbac0bc445d8a1f16661ace18dba124b99277676197c886 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15427 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-ros1_1.0.0~alpha.5-1_amd64.deb Size: 3207276 MD5sum: b784b1ba30149f85238e556b97e2c219 SHA1: 2678fd6af37124aeb452b8d91a8592d675517fa6 SHA256: 073748b1e123b0657a1899814c2bd5c891570c9429135697bc804f1e190321c2 SHA512: 367b09b34c283c0f5acccba8c7a5966ac7af9f1c48a618aa2a4378b1c55a71075bce54cd5f968d1a0a93b82681633f6141fa0543b6aa49ff74319db4647b7b67 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14105 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-ros1_1.0.0~alpha.5-1_arm64.deb Size: 2964744 MD5sum: 1b388fa5dc0946e35a65be4ebd0b7c39 SHA1: 4e83e50ab03079b033663de805afddfc85f769b0 SHA256: fda6d33fc53622cdc07baed80fc7bf49e348ee02db51ac35181f49bd47c6e663 SHA512: 1514d6727d832c2239051e06a6315031ba6a8c079a71a06c4a51ffe50eaa8a72945edd318a06e504a8b778901297de5f7bbd03505a520f6817324aa3ee3ae604 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12301 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-ros1_1.0.0~alpha.5-1_armel.deb Size: 2858244 MD5sum: 2f856252bc591e5221ec74a085d80d64 SHA1: 0f220904a29631fcff43c8cc5611dc32395e6c90 SHA256: 7806498d2c3cfc7e400aa652b6fb1c4528c9d026e39dec2fbffc8d368fa982f1 SHA512: d0afc1ada8fb5cfd8689fbb74f37cc308820cdb4f18599abe92e5c0cf687cb18ce7990f9cf4bc552f7b245c8a8075db593655fd53c7cb8acf309bf12113371f0 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12080 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-ros1_1.0.0~alpha.5-1_armhf.deb Size: 2829316 MD5sum: f396e01b9570619f99791ef07f21919a SHA1: bf21dfdd3f5d4c6d0fda4b88a088fc442e4b3f69 SHA256: 35e732dcd824e8d2586f75626bfaaa855ab7023bcfb6dcb9f2dbe790786c749f SHA512: 007fb930f7e59804ad959513edaf79f250369e8d0d9c5b8f3427b81daf5580c0361cadac141891583d9061421d27e4a675c5424827c886e560506a331b91719b 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13468 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-ros2dds_1.0.0~alpha.5-1_amd64.deb Size: 2711152 MD5sum: 57eb3f872d3916359adc16503eddd18a SHA1: 2f155a06ed2e8877cddd39a45b41399df48312ed SHA256: b9af22fdd6bfa77bb82bc7075615fa672a39ad4f723eb77467f737e1af4e317c SHA512: da810e323b86f2469dfcedab5b526dc09ac601e37633dcde0b560dd8bf3ba6a9f81e7cfc7cee49217d434d5cf3926e11ca2353c399e56e831640eb4556e5551e 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 described 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 maintaining 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 architecture 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 possible 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 bridge, 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12226 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-ros2dds_1.0.0~alpha.5-1_arm64.deb Size: 2473992 MD5sum: 32ed07a963c9c1755abe8d9c76fa0060 SHA1: 37d8487260ffbfe1b35035f876b152fd6b585135 SHA256: 33a165557deb126de72483009a8078b5e475ae4e4f5a192143cbf19e228bba75 SHA512: d998440ab6920c2b2f363b1a2b3ed9ed350528932f5759c9e2b3e2e9d5d316f6e94ec5a62cf777de2d7a0c86cf69f39f2edd5454aebf5c5e00e15c4d1060e892 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 described 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 maintaining 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 architecture 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 possible 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 bridge, 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10303 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-ros2dds_1.0.0~alpha.5-1_armel.deb Size: 2338852 MD5sum: 5d9152fda38704d81e036573016f2566 SHA1: 078bc5b9eadd7f20a840d9502627b849379d636e SHA256: 84fe8b0842b41bcc5656d654522985177017c8485e32b51166e52e17ff32f610 SHA512: 47c9b773556759728d05967615460e7365bb0e8326becdc56c97a9298acf3f0f296bddae7c4b726fd1e88fa38202f5bd360e042f7c0122126bf63a08875d8868 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 described 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 maintaining 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 architecture 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 possible 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 bridge, 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9925 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-ros2dds_1.0.0~alpha.5-1_armhf.deb Size: 2348876 MD5sum: 887d5bd58089e9d519ad24f4c8a49b51 SHA1: 10b5b23209b1717d3a89bd7ddc0758995d986aa0 SHA256: db07218c7dea8e64fc284ee7961a32eea44d71735e92b30ff4267eef6f02c852 SHA512: e277623145d25610ad03a46ca3219456b170d7508fbe6e9daaf23b86a556980582ff3f902a9018fe042b0d6f4a611d810c482e558730fbc0060cacf7e727e203 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 described 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 maintaining 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 architecture 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 possible 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 bridge, 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11960 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-storage-manager_1.0.0~alpha.5-1_amd64.deb Size: 2280388 MD5sum: 9dd0d370db0128df75b8a26bd88bde60 SHA1: e84326dd1615f16c1a3af78a7c5a48ffd35d29d2 SHA256: 3e820dd57e1a882904d773667e02e9f700f8c940284e6ea9db2ca74713a64c46 SHA512: 57c4d59374e3d9fcaf3376ed9d516f7aa1680651655d87bc15849687699acb6fccedf7916f40b6c7d20dbcabe1b3e3a60e1eea95bc9b95653e6b9b5a664c87ed 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10722 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-storage-manager_1.0.0~alpha.5-1_arm64.deb Size: 2065616 MD5sum: 25ed65c3459df6f24ed82ff0d2076745 SHA1: e889f6749922e907f8c3275ff6e07714580b3c85 SHA256: d14eecd19cb8b3cb23efdd19bbb634b27f9cee57c0fed8d11ccaf46e59efd00e SHA512: 9eaec5a3b3c9bffd1131263e1f7a34982efc5b1108c9a8c1e5f5b4c53de516d66980f6d9634e4ada19d1a6782ac4a63e2fd5af41d4ec3dbbc87c9144d392334f 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8965 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-storage-manager_1.0.0~alpha.5-1_armel.deb Size: 1962292 MD5sum: e35dcbca04c26a3f1315465cc8a7f7b8 SHA1: 45c7482986909df5a78b5a3bcf4b1fe91ee4747d SHA256: 439ae3d62af6ad5fe81c196b390211c42d92aac4f09abaf7b1079d16f5f48497 SHA512: ba3597a99f87f68eaf968509332e770eb4b3c03c313dd49e5981b3dcf82da23083263a691d5712ceee834528025dd9884027ba766db75ad5ee4f9e6842c75a6b 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8836 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-storage-manager_1.0.0~alpha.5-1_armhf.deb Size: 1950920 MD5sum: d3458c8f04fab7056612c3d680950639 SHA1: e59420eedd32aee6065cc2c107cabc22cc613f5c SHA256: b07216c26efd14a7f71414e22582fca59acce7d38864e8b8f08ad9c4df2df2f8 SHA512: 7c3aa0e38096459ba4d78e0672ef60dea58288b77efad04f622b90b3e8d27ed58d1a2a40d8af7e5d29a2d3d0cb10925cd52beeed76b2d6b38c42fb656e33beb0 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14066 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-webserver_1.0.0~alpha.5-1_amd64.deb Size: 2656972 MD5sum: d75c538e0546e836f8835378e274a5aa SHA1: aa8ff298bda27eb40189acbbd98651945413286b SHA256: 4dfd02618f75c8f6472f2ebb21eb35db3f0dc37160377159fa75bf5aa814aaf6 SHA512: a8580609282faa0d1d29dd8a33bb38969c5cf2a91ff1cf520e0dd759df830e8c5d77a0cc9aeec9ef452a7790b6a748be217e2ec46ac54b463af756ce0287e84a 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13232 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-webserver_1.0.0~alpha.5-1_arm64.deb Size: 2461564 MD5sum: 1dd12f42d20ddfd7396bf9f00f88e136 SHA1: 3fb3040c016f531c25dc2b75263afcf99e57fecb SHA256: cf9119be24fe3cf10b96551177a59a5eb7db1d93b2799500c72819f8641a7c85 SHA512: 6dca4c48da0da50165a24a4eae60435be9dfffc0750cf8073cb1c73e03e4d3e71888ace63ffe1135da3a3ca97049814da5f3f4328cbd918d3e32445489345c57 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10873 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-webserver_1.0.0~alpha.5-1_armel.deb Size: 2250172 MD5sum: 4d45b5c3f6f1ac222216ca3253efef99 SHA1: d255cf8f47f85402d09f0c06aed8f138e138e542 SHA256: 4a52ad7fb4b34e9b3689c1184ab8194eb7ae22f044ff07d9d62729c79574fbbc SHA512: f3d5b4e8f8ce8f341e30f90a10c52d639237ab6ab3ef69eb872834c329e648363ee435289115c1939d21a265b5df61bbae7fee1d8a9755b9a02c5c59e48f432a 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10718 Depends: zenohd (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh-plugin-webserver_1.0.0~alpha.5-1_armhf.deb Size: 2232180 MD5sum: 3cbe3a819bc4a163719a3518299c5eae SHA1: ee99f3f91adea5c0afd051bb42592ce6b8874ba8 SHA256: e2478a9a1f4bdc2c39bbc1e6379e4025acaf8259e27f87c50596fc442bea4c6d SHA512: 693417eeced4aa9301b416f3b52a7409e75c6cb34b0f75ed77e52e70e2f15ebba662cdd5761f54ef4b61a1ced052cbc44ffa7b642b2325a6f92649b78f32bdfb 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~alpha.5-1), zenoh-plugin-rest (=1.0.0~alpha.5-1), zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh_1.0.0~alpha.5-1_amd64.deb Size: 17304 MD5sum: b43f8ee1ddcf3b231c86e08fa26b7e7f SHA1: f9b1e601ed036faf2c00ab7e1f7e6a3d442a0f0d SHA256: d7ab2299b062aa3bc5bea4dacf70eb1485e09e760adbd4c091ed7d61b3d9fcbe SHA512: 6968fe40c50a5f5dd6fe12a884aa4fe7f378aa1e9d4952c783c69bf51c5fc20d27e41590b009b2985e23b8ee9439ff37f03fa173e38ef89858da14f68b51bb31 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~alpha.5-1), zenoh-plugin-rest (=1.0.0~alpha.5-1), zenoh-plugin-storage-manager (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh_1.0.0~alpha.5-1_arm64.deb Size: 17300 MD5sum: 2dfd0029ed1aaff7a377fcdda57c1987 SHA1: ff43c3f9e366ee7617f857e0bf83ab31dcf76830 SHA256: 30854404c9e6be2fa77644d381b0954beb97a248643fe1809305daa823c9d650 SHA512: 82adf8ecbc632e6507c55941f1eadb427d88f37a0453c9234b87c46d7441f5afe53f4643aed22a37e5c8cbd6b0f7be84f9464631a38f04330408f786dfe4efff 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1), zenohd (=1.0.0~alpha.5-1), zenoh-plugin-rest (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh_1.0.0~alpha.5-1_armel.deb Size: 17304 MD5sum: 6f6644b4567c9ffffde713ea7dd133ee SHA1: fc968ca2a0ed255d0d9116fe0bdb6d6af2edf505 SHA256: 736c7830927893a27a259c389c98cf2375fb6cb4599f55586a261994666684ff SHA512: bea20396b67987819ea976caa4d1ff211829fccb911781c32c912d265ed95856ffeac0a47f51403dc2783aecbe39cf9062134df0b6d97ad8e73f67cf24c18dda 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.5-1), zenohd (=1.0.0~alpha.5-1), zenoh-plugin-rest (=1.0.0~alpha.5-1) Filename: ./1.0.0-alpha.5/zenoh_1.0.0~alpha.5-1_armhf.deb Size: 17300 MD5sum: d2a6788eb5ee5307b8fb7e842a07af8b SHA1: 014bed9d4bdb50a03ff2ba3ab73763ba2a41e02e SHA256: e793104541c45454aee61e6acb9596c44c326f776b5578e36de34955dd55cf5b SHA512: 208ec874a071e20a6dda14c83f02ba5aab1725f118a45afab3bf39b8d021751418b52c904c2c9b36d67ff65510fd4314873935a1bd0fe5b0b49613bfdf421328 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18522 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.5/zenohd_1.0.0~alpha.5-1_amd64.deb Size: 4508940 MD5sum: 32b0c6ccd22f0ec473276f59f41f7ba0 SHA1: ea9a17818f6142dfd535e513d9a07deb39777e64 SHA256: a3b2ed8ae53bfc3be87f040beee0e2b7e4975c495edbac89c1d7796cbd5fad9e SHA512: 700cf239a8ef4363747ee815a9fa377af3497f47b74e30aacedfb4409b3f81c681f92b5b05bbfc6a124862692aa193b7ea4fd712ecc9b0c09eab8aa0424fe72e 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16445 Depends: Filename: ./1.0.0-alpha.5/zenohd_1.0.0~alpha.5-1_arm64.deb Size: 4030416 MD5sum: 47490251d5d6a3b324f2596a0bedb1a4 SHA1: 5a0fc1f2851703c1d51084e8d6165572ed9098c3 SHA256: d3f07a33196082bdad89667acaee6169f0b9a1118ab52a3c5ce45dc893a4e314 SHA512: 62898fee7897962f0b8cc2459392b9bc583fddec0af2ff2c374a766d856855899d82f54776658d89b463b2613f1485e7748a07edba0783f7871253cad03fadd2 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17896 Depends: Filename: ./1.0.0-alpha.5/zenohd_1.0.0~alpha.5-1_armel.deb Size: 4379940 MD5sum: c0186ea2e6dfa452c0d4b45dc1d8af02 SHA1: db9ae0e63fe01c3255b354d40a34294a21ad37dd SHA256: 1b2bb3f451403c7e59fdd4b6125d28b65019af37964f5411cf7eec7f3cd85edf SHA512: 9170b99b5ecace78ebd34e7e4d4aa77a267b4634a29f768c0142af8bf2031f653281cecb3d762b3aba3a5e680d03b712179a0ef2bf76001a94888231e3471611 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17660 Depends: Filename: ./1.0.0-alpha.5/zenohd_1.0.0~alpha.5-1_armhf.deb Size: 4432912 MD5sum: b5b8b5694ba2f87eab981d853c56108d SHA1: 1e7e3f03897b24e7a4a47cf614fae4b4f0dc98ea SHA256: 844d4f952b01fa1df2682c9a22c5c53d19393ef509e7aa167cbad11e4ecfb997 SHA512: 810cb09f173e1cea8042eb9b98af28b4df4518ff6d484b99ac2cb71051868d4b091d1c3475e267c5ea87a469aa7ba5edf1b876c9ee662e2d565bad6455b3bae9 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20744 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-filesystem_1.0.0~alpha.6-1_amd64.deb Size: 4576576 MD5sum: 18eab4093e1d1aac5bde710ac7d34c83 SHA1: 34784f87c7b91d925f15929f787fa2a52b9c9441 SHA256: baeac24cb834d7b1cf45bb96204b588e2e95a229a2eb43c2e4a6ae0340ec5c1e SHA512: cff21ad64d190c057bb93a3c5ee7af0605f4066eafcdd94ff88b61985c09c0ab33964546ab7f1a1b257c0d8a2d7ed283b84471fb5aecaf3b8b851af96911f460 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18874 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-filesystem_1.0.0~alpha.6-1_arm64.deb Size: 4112576 MD5sum: 62b402e2ba0fee9adc0d224901f9d630 SHA1: 6c365f14b914ac77c66f25ed8bac3ec1b47abba8 SHA256: f84ea8ab8957439ca2a296df6f3a6a6e740b0e890524cfe6066d2d34c54a1c62 SHA512: 7eba8d220a73082225e6aefd5dd64abf12d545e3accd6c7662b54bba19fa4c9af9c0a3b5cf0a179528f835375ef41f97eae1890c654e20b7a591ce292966b553 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16469 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-filesystem_1.0.0~alpha.6-1_armel.deb Size: 3896972 MD5sum: 341e18d82bdffb67110421b14eb80ca3 SHA1: de74327f964ea808552425bfab52a5fdc95bfba3 SHA256: 38e0211d00a1f526d698562758b4cfa6f3f6e5742fe9abdefb3f1e54a40a3f1b SHA512: 5360777def8426869a0b6397111a0a7fc8a61783b9ca7bae0ed754031f74d23b5294eac1864b47bbc2c717ba3fa39d7d46129b100f7ab4be86b2b94808a4eb74 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14592 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-filesystem_1.0.0~alpha.6-1_armhf.deb Size: 3993540 MD5sum: ca2b45ed5211dbb39115ed6d11e71746 SHA1: b3ea6a6791e920d9f03bdc5256206c376c619b8c SHA256: 2338309e1276cfdbbf0c3df2892c7f7c508c96b570944d14366699749d8b98ab SHA512: 6471fd8185dc44d5ba780ff8159829cf112e8a49f1c2a31b684e77ca94943169dc2e837db0231510c23fcfe5593e4a329771d2d0d7514f1fd14867160494ec23 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15587 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-influxdb-v1_1.0.0~alpha.6-1_amd64.deb Size: 3090900 MD5sum: 4cc3360775f87c755dda0a51e7c2a64d SHA1: 2fe8bfb540f8f01674695ec1174dfabd7d7f6407 SHA256: c3d6d14015c883e9b1ad0570a31234e02dcb9d7efa3a2835172f7c44025fd677 SHA512: 8e76736357e75341a5f7dc0591df3ce425527da078289d33085eca5e3309c9a78a31d14d12872379a254f3c887ae1b026e1a861a11a44fef4cc6b8c7391d88ae 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13931 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-influxdb-v1_1.0.0~alpha.6-1_arm64.deb Size: 2774820 MD5sum: ff30277531b082ae278807fcd81a4a1d SHA1: d0e05119cb3615d143173f1891bd8ff989a1c156 SHA256: e38dd30d0b57b84f8754a003437c53467ee25b50bad658ab319e17b6e4c2c2cf SHA512: 4ab2244d10d2283793ba9e1e416bae22bcb2b42a265343b57460bca3b4dfbc7566392a0432c416e3db431d28c71f1525d9b4479e8b71f7c6f6c5b6d8c1eda7e0 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11748 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-influxdb-v1_1.0.0~alpha.6-1_armel.deb Size: 2529452 MD5sum: 319e12f64ba9438ed841a4d4486f4f9a SHA1: 7312828f833042c6ea6afc3cc5e1a8b2aafd4045 SHA256: fcfb13ebf2ef8b5d3bb7c96ff5fdc5060258eac0cd51eb6c2b24652205ddd2fe SHA512: 4c27e6a22cf2c8153c0a5f4993c4b063dbfbf6b8b23527885fe448da34321e76344430a3b7fad2a246c2044f9879f6012a8ce74199d3d503c3b48359fdab1dfe 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11620 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-influxdb-v1_1.0.0~alpha.6-1_armhf.deb Size: 2520068 MD5sum: de3bf7ee819882d3ef237aab32a9786a SHA1: 2b9226d0a17f4db04bfb35a5cc03b94af530aa9e SHA256: 25ce0afb93566f5c83551a93de38dc22eb4fd457f14e42e1210a5c546c6d2abe SHA512: 8484dd85b98a786a9d27c7b40537b5cf8e4a25ac556f34e5f3f17e3956a922f8e17723ae019f8495c345f88e84995e94d88263ced04148ada40dbe20d94fb684 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17111 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-influxdb-v2_1.0.0~alpha.6-1_amd64.deb Size: 3754796 MD5sum: c2622ecf9712b3e0a0f3c4446f2dbfa0 SHA1: e40841610149518e7563f5f03b031174299a882a SHA256: e35711aec1e27c292f8c8f2c4649238352ab88d701eb70f6672a79d947c1627f SHA512: 88ef69b0890c72e833ca02d14fde78502bceb1cbc2d64ce226133cdb9ffb967eb99dc9094426ed0648931b498283168a39dcc55778e7e5c49d6f7463c1ab2864 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16115 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-influxdb-v2_1.0.0~alpha.6-1_arm64.deb Size: 3438468 MD5sum: 33e308cf992b0c0cc4b75655b0a896c3 SHA1: c445a63f66ecaab175f3e652f1977391266c7903 SHA256: dff14bdce100560338167ff34507144976701d4724ba51eb983763044cae2075 SHA512: bcac7bea2b259c5b2fbae876c0f38bedfc78ba9e384135ff3647c08901a76400513488b93b9b04bb9d8d32c7af6e1290f07e95fa720c4ced4d00f1701c885635 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15405 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-influxdb-v2_1.0.0~alpha.6-1_armel.deb Size: 3424648 MD5sum: 2befeb5188d119d9d7c7db226141b0b7 SHA1: 1f6dc0f70758c1c8c3a8401606b7042b376ae5e5 SHA256: c7329a8a7df126c392b2664ec7417d41b0e68fe4d6100f16657f0973881bae6b SHA512: cdae6ed65a85062be87bf202808f46480b4a93c37f21d1384a11d2841230345d75645df1ff3f19ced7d34ae9884de777c8273276df5ffcbe6c8b1479e0e1e61e 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15294 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-influxdb-v2_1.0.0~alpha.6-1_armhf.deb Size: 3468568 MD5sum: d7d90fc0b4d3ac9f33693ecf53b54287 SHA1: 184efda36a9d9897d80cb06264e5763438b4b752 SHA256: 43a6265ec3f2ad4b09dcd44d735c0b9711f272b5145e1cc52798515b44a4e48f SHA512: 0ac36598769e8458178f193e249f051cf76c3fdd15a5e754d3c11b7a070bab297f7b23bf4b6fc01d3a367ff8e3124f8131a2f0a3542299dbe92e0027141f7288 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20377 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-rocksdb_1.0.0~alpha.6-1_amd64.deb Size: 4526740 MD5sum: f251e2ee28809033d87fa60086eda282 SHA1: 8a484d92964dad5778c524b58557fe06ff3d615d SHA256: 189c78ec4ff606cfcf8e6bde0c8c8c2f4cad841f6786bb947737f2c405b3f0f8 SHA512: 43598ea48ffa3a8c153d0065dea86a86ea239731cc99a666ec0a31d536bd2754f8a11f3182f9f4f9e4221a4d9eaa1805b4226ae73e13fda2b6dd04b237863ba1 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18400 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-rocksdb_1.0.0~alpha.6-1_arm64.deb Size: 4050016 MD5sum: abfb351171715b67a14f78e5585827fb SHA1: 250b62a8607d5656c66470a9516a2854653eb4f8 SHA256: bd2630d6d80056760a06deb31ce936e009aa2b16f4514a0a5dee4b94334a7ed9 SHA512: 2bddc1ce073c7915f71285bdd3192c08d2466ced600cb1d94cf06f3f762fafcbd97d2d3c4154ca1e4a09604e470961db83dea47fc3d334868f9d7c4d82d1309f 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16129 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-rocksdb_1.0.0~alpha.6-1_armel.deb Size: 3849432 MD5sum: 680649936e229d34726a94979b6781fe SHA1: 3289dfad0c7e6624a9fb1ee5f2ebe781ecb7ea4c SHA256: 81801f22667dc178289cbd5c16f4ce203845237088394007db7df266689058a6 SHA512: 5c8f7d96edda07eb6a62a398f1cac4078959efaffea2e4510046b5182fca4ccb060f7ade0e10dcb1487559c0f1ee85fee00cc5641517470320bf80bc3f7f36d1 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14206 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-rocksdb_1.0.0~alpha.6-1_armhf.deb Size: 3950368 MD5sum: cc3f2e724124189e0c4456bd242bc3bb SHA1: ab8b90654c0511082e694004d288f08fd966f758 SHA256: 058552b64162f1671a6fd36f7fb775db6275a9b601adaed3798d9dd064136164 SHA512: a0603a8077cabf16cb9d4726047777d25e6b4a6c0dcd5de9ea1d97fef19dd5eb3c82920557de564763ddf33112f4acbc56d289d37bfab97ab389d22e62cda6bd 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26885 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-s3_1.0.0~alpha.6-1_amd64.deb Size: 5402176 MD5sum: d74ec8110ac6f3c39e10161ae43803ff SHA1: 3478c425fb4a8021ec97038fb87f10fd012259c9 SHA256: cdfbc02853a1ff569f40f49a325527e1d0c19bea60fcee50bba55683c3e279c7 SHA512: 0a441e5f0c3ea1aeff1ef4f7d3c0ce76bf997e3e39d532601bf257a879d03e0bcddc556f0209187508ed40f52102b0a619786dfa03fc110a6710a8c2722238ef 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26147 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-s3_1.0.0~alpha.6-1_arm64.deb Size: 5122756 MD5sum: 729f3cd4289d4b1373cceb0e6ee278da SHA1: f2f6d9f11310e7e1f89e6fe02f3038d23cd33014 SHA256: d38b4fe03926c1179b0706e1ee7271034e533cff1209ebccb89e6e46713955d2 SHA512: ca995e737a7a6daad5a5a90f37522a6a5e50ee9239691f13126ca2533fe6c9af5b07ced393771f62bc2247c3efc8c0a879ad8a5043cf95c2058c7fcdcb7d1d6a 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24923 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-s3_1.0.0~alpha.6-1_armel.deb Size: 4988408 MD5sum: a148cbd1e7ea816ed20b8bcff39004c8 SHA1: 6c86186aad815d7fee74cdeffc9853ee785e82d6 SHA256: a2871ae34b22cd495ae0d29402f62202b2e1780fbbf5eda36f01ea3780255096 SHA512: ef20fda0d29a0744e39e84a1d17a160ede0052e0b6e6f13b22df78db80552b31a9498c4daa921e9d4efa305993000588fc9679612b3e901818a207517141b68a 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24690 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-backend-s3_1.0.0~alpha.6-1_armhf.deb Size: 5034944 MD5sum: 89113ccb8ff53dfde1d418b820dd1c6e SHA1: 3c5e6e1bb57e8bb6a94f1f1d434db8753f61cd01 SHA256: dbc610769b03657fdc38740cd7e20634416f30320a2f63c9dc82c55e714b3091 SHA512: 80b72bf16a85dd706814ab3e6541e0b2383dedc3d47659aedcb1a24756b4bf038ca597bfc93597f461c9f220b18b316ea598d9005ecf7b72d35729529753cb61 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20780 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.6/zenoh-bridge-dds_1.0.0~alpha.6-1_amd64.deb Size: 5210840 MD5sum: ba6ff01990cee98686a5ebadd93dd6b9 SHA1: 0fcef2ee3a8aa879a00bd3ccdf48540f520e2274 SHA256: 101dc5fc944bc638891a863fbd019b4c24788195c499338a2c4d53ddc70c4faf SHA512: 15bacf88259ef3a90d22e30236028ba6ee40eed2e487eb64e68fed5c1be612fcd1bda0c8e5ee0323eb23a63e60743a531a1ea9eb9ceed5b70dbc8d550e8288a4 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18884 Depends: Filename: ./1.0.0-alpha.6/zenoh-bridge-dds_1.0.0~alpha.6-1_arm64.deb Size: 4694512 MD5sum: 48f3584878f2603015475b30a90d6fc2 SHA1: c763b38b6959639657f18a286a49bc9003a2618d SHA256: fee0b96b4077c040526dc9696dac52d24ecb617668ccd91797f791ca83e9b073 SHA512: d5d61b0215650dff1dbd7ab2b6dbc6e2a3e2c17d02a17d48e59ac397597acdccc41f5d1d781dcba6f2124984933b638a6b5ded0250216c426c8513da0f1ec88e 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20144 Depends: Filename: ./1.0.0-alpha.6/zenoh-bridge-dds_1.0.0~alpha.6-1_armel.deb Size: 4984372 MD5sum: 96b94f47c9d14e09b075814c16005448 SHA1: 08494c4acc89401de9950cf546a37cc79052dcea SHA256: a88498743582ec615aad09904ae173bb1f5d1c31539f461296585d177ef574dd SHA512: b6cb89f38507e3777e0cd62c0f1c97d3bcf4375d4e86fe6739345ba6734b88ac4981946c6a02b8bc48fe851dac4516d2a1e3d5f28c7251fe2b3151fb40a20ce1 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19657 Depends: Filename: ./1.0.0-alpha.6/zenoh-bridge-dds_1.0.0~alpha.6-1_armhf.deb Size: 5037284 MD5sum: b1f50b500eaf7b53663f975d30356b41 SHA1: ab3c334e123c7cccb14f7ba7c26251ab6c6e93c9 SHA256: 77afda024e446dbdfc93e8220e694eb282565cb10effab31a6d1c18502865a5b SHA512: 2a9eb92366bb1c6f09da3dc8304bfbd3f5795e513341b4b86d98956a2dced538f2ebb289aa61ab16cc07404a916a6594365ad8e311391cf08571dfcecffddb2c 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20645 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.6/zenoh-bridge-mqtt_1.0.0~alpha.6-1_amd64.deb Size: 4999224 MD5sum: 0ac46c7f169c9733689b7519c7396bee SHA1: daaa1b5bb17737981a21b2a1fd8b95a7c4edb108 SHA256: f9f5796c1ebfc7814a2805f21977007d5f5c8cb9881b133ebbcf6622ba3f76da SHA512: dff1d02da8f4d2324797ab9c6df22a2d2e668e451bc785af962d959e282a06d6dc6cb22401f069ed2f014b8205108178d077b0a4a52f268bff9897ce16ea9531 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18688 Depends: Filename: ./1.0.0-alpha.6/zenoh-bridge-mqtt_1.0.0~alpha.6-1_arm64.deb Size: 4501932 MD5sum: 2d7cfcd64ffaa2642659a1d2d4d6f389 SHA1: aa68b66ec7cfac4adc09634a528d2c6265363d6f SHA256: 7c4afea97039505132f0f339148b8b61aca8108e95a41ad1a04ffe1653e82901 SHA512: 8ce260dff777e5f411f568f90f70c8dd3ec1e782885d5b2a178adff40850e8062c3f80cbfc7b6da91680d307a9ab34c58c32f63bf4eccd7270b20148a78f51d5 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20119 Depends: Filename: ./1.0.0-alpha.6/zenoh-bridge-mqtt_1.0.0~alpha.6-1_armel.deb Size: 4802712 MD5sum: edb7fd6b30e2c6b1ebcd29d6b5adbc16 SHA1: 158fe98e13a45fa5524aa5fef709a871c99a95d7 SHA256: e70867380ef7c532dce1ddc5ad555e282dbf27c03760bd6e8b54ec4b9039faf4 SHA512: f20028ca900c6b215c764198caceadafc242e89692a3dd21ff1e8ebe390a05d6b96b2010141aa2751de213babe6f4dcb80aa8dd60c03e56c208b943755f90d2b 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19852 Depends: Filename: ./1.0.0-alpha.6/zenoh-bridge-mqtt_1.0.0~alpha.6-1_armhf.deb Size: 4832484 MD5sum: cf85233bec5f8cd3de27e1c60e9a0d9e SHA1: 1f081453095d510bf48550aa41ea97611ce57e5c SHA256: 4beea3c61ae40b2aeb4172a5eec019cae78ac05fc6c18724e8b2c215ef40c882 SHA512: ab86fb285b521c0013d1d56ddb345820fd7838144330d9b3dbb4551bbf6077c1cd58af4da5c1ed98b6b8dcf972f988e68591ad31666333fd6f92b78021b9eb54 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 22077 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.6/zenoh-bridge-ros1_1.0.0~alpha.6-1_amd64.deb Size: 5375044 MD5sum: 87189f439a22bca31bbae6c365af1bcb SHA1: 0166b8e7ba508f1845b57e1013cb2bdbe73f88d0 SHA256: f8a9bf9de66f5a2c777b918e5c518612ccab4d68abbba79757b5bc517843ff67 SHA512: d879588903ea26355c601bfc7fddeeb8b7aef4c3a320f76e17915b9c4b9e35cbc3143c1dc80c19bc6fff6f54cd3a1d0ea53d144509e150bbec0adbe38af8c4f3 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20064 Depends: Filename: ./1.0.0-alpha.6/zenoh-bridge-ros1_1.0.0~alpha.6-1_arm64.deb Size: 4854012 MD5sum: a5008622b4726b03eef6a5cbe4c7f5bc SHA1: 62f11a4eda45ce1b898336802841a420a0b6dbc3 SHA256: f513583102466d5b7d2e1d7edd37269d7d031dd38bd7064293bef08d149689a5 SHA512: 43db9158ad88145e583fd551f5ff074c522f9e118ee040940ee12760c197553ed6b010db29ecfa0485f385a3aee87abee267970ec949d703bf073dcb0689c710 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21496 Depends: Filename: ./1.0.0-alpha.6/zenoh-bridge-ros1_1.0.0~alpha.6-1_armel.deb Size: 5183448 MD5sum: e67556bf7a20855e2bde0c36453d3ba0 SHA1: ed47b6cc445c1d179fcf1248865018a910922de6 SHA256: 463dd65692d63603bf46f63336b07660cb2148275ad6cecbffbbde2cc510ef69 SHA512: ee06d23a756c8b5511108a38c4b7bbbf5af84352bd681f6c7cb02ad706b659747f7f044760470d118204134218c2c81c3d89867a1f46b185dbca03c7826518d7 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21201 Depends: Filename: ./1.0.0-alpha.6/zenoh-bridge-ros1_1.0.0~alpha.6-1_armhf.deb Size: 5211736 MD5sum: 6ed369164d18b1e084843b5dcb6aa548 SHA1: 86ab8ed62756f3fb1742c80427d320eba830c1d6 SHA256: 7c3f036a204aa14c66243b0f138a0e6403f43ae9eb7a21bf79dac14831b56791 SHA512: fb7603c3eb27733c536739a61306c08d4e1ab87d27f1b3d672e2967f2da598b95c33b23ce57e6f48c6f51f2e1cc00340f683157fafdc685afe6c33808b9eab14 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21414 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.6/zenoh-bridge-ros2dds_1.0.0~alpha.6-1_amd64.deb Size: 5335604 MD5sum: a0e82f943b3045ca5df5dd5efe619a2c SHA1: 4a16334b110ad78faf64b6442b21248ab117e4d0 SHA256: 7194664372ff0e082ca2f21e78c639e249ec7a39138b6093dc32cf80e79a64a1 SHA512: 6a7d3be0f902414a59aa11dcaf970e97909ce02dac5c7c3eafa55ab62151a633b5760e2bb3b10a85b9a18552cb4360c7df2ea093be401a3be74e65e44a032630 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19476 Depends: Filename: ./1.0.0-alpha.6/zenoh-bridge-ros2dds_1.0.0~alpha.6-1_arm64.deb Size: 4829068 MD5sum: 91f317d4b92da757531c1a56964c3233 SHA1: 7b22042d5447d320ced2165f48d139ad2ccbeade SHA256: d208b00fe9343ccc95446b2fcfdb5024a3dfb02c0bc2047a52d594dd02f45df9 SHA512: b94678663ec762fff436594a4f12c44aac1fe8d0b699140efcc71c517bc84842c9000c63ebe4c4da725abc3eae1d205cb4e243aff9b311612c39fc53aee646ef 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20748 Depends: Filename: ./1.0.0-alpha.6/zenoh-bridge-ros2dds_1.0.0~alpha.6-1_armel.deb Size: 5116188 MD5sum: fed32c60aa047f0becae23dda2b8b8c1 SHA1: 4bfb2528dbab6dd4bc189a9f214dc57bb336a869 SHA256: 4ed5d0000bbf0fcddd2f84d30a232a5e841e9f47e8d710cbfaafecf2a5152f77 SHA512: 140d2ffddb14ae5e8cf61ace5260555237706a4029203faa25f9ea5f56d252e4c3c12e16029bbb65da74c8d9229e3639e3c25d5238dfa6aa58920c5b556a1f7f 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20252 Depends: Filename: ./1.0.0-alpha.6/zenoh-bridge-ros2dds_1.0.0~alpha.6-1_armhf.deb Size: 5170092 MD5sum: 4a7f4d4eb0ec6b017cfb22f396ba83e0 SHA1: b93a4a7e27bca434b5427cdc3f0b5f276e10e422 SHA256: 4fef3305364f60614ac0b0628ced439121a98acc3ebb486be2811c4e35c77274 SHA512: d21a678ee35f50342a5887e41ca41be955a797a066c96e601f95e5443bdf14ed2d960840e0c94fc28903933cd81119738d613ebf7faf15dab2bd17b46031e760 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12624 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-dds_1.0.0~alpha.6-1_amd64.deb Size: 2527112 MD5sum: 66a462419e97809db81fd4299bba995b SHA1: b7ffa565c8329b7fe1c186c56cde53b5d778672f SHA256: 0cab27d979a490ed828ba21ae17b43244ce7a863da42b9e7bf0009db70118765 SHA512: 0a0f738e319eb1b9e7a9cc58d44fc7b236e67845e868f0e5e048fb8ddee76df4abe294a7e4b3fc5ff4cb04e4553baaf0b59960a8cfd5064aa3a16c14a93a9220 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 described 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 maintaining 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 architecture 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 embedded 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. - **`--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 information is 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11414 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-dds_1.0.0~alpha.6-1_arm64.deb Size: 2296612 MD5sum: 060a887a61e9b330a5048a85dedda10e SHA1: 7f24e48321c97f7b3025e6f4d061dd6e2a3839e7 SHA256: 44703972963fe524be03c6a0ec8c6174f60f6b43c8361dae25b396aa0db0e6a7 SHA512: 5af3ec665b8c0184f63846add7c0f2c8763cbcb7d0540303a50d33f83d7a8cbcb591ec76cc5bde2a896af13502923219e3e285b15fbf1e1c95c57f3b2fbced1c 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 described 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 maintaining 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 architecture 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 embedded 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. - **`--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 information is 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9479 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-dds_1.0.0~alpha.6-1_armel.deb Size: 2153756 MD5sum: 765427b46254d43c47ddf1eeae5c7eae SHA1: 3e9e18e45cf0e521124c5d8dd2de8e0f13b3b7c9 SHA256: 37579de1c6042ed61f4f252855d71c191f6c4d976f6fceb9f27b2c2f30ba451b SHA512: 458c75ff65eac056441e497964119d272eb35eb07be2cf7c1137d57e01dadcf260b30a5dec4d0598c6f00079bd9b58113689e9d889bd67560f48f037b0cc216b 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 described 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 maintaining 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 architecture 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 embedded 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. - **`--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 information is 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9117 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-dds_1.0.0~alpha.6-1_armhf.deb Size: 2160336 MD5sum: 108f5534c9b73168b8ec24823d9c8ea1 SHA1: b3109f40629fe11aaeda8401b6949708bfa496b2 SHA256: 632445ec801da9218db553d1e01806939a7974fef598b8ab58773a9b8fa29c67 SHA512: fdd8478b7d73b17804ce20c669a8b2f2b838ac5dfcdd2ada4878c8c885087b529426e738ec38a1d85a00328d9392934083bac20bdb8e04ed634411715cdfc44a 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 described 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 maintaining 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 architecture 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 embedded 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. - **`--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 information is 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13509 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-mqtt_1.0.0~alpha.6-1_amd64.deb Size: 2843508 MD5sum: a3c397a85c42a45ec8e7e61420521651 SHA1: 6e38bf1bcbb41754309aa6be2dd9071d05320497 SHA256: f44a2c5633ef432f8f2cf49e3ec6c45443a9d887b1e7309301157e8e5c73146f SHA512: 9fe7e8e6bbdbdb1a0f256ddb256a812ae07eb8842bfbe192a5955abb1b257c243528986ec6d56c3ebb99e3b6b02229cc4858cc6970643fff0156f6053f356ea8 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12201 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-mqtt_1.0.0~alpha.6-1_arm64.deb Size: 2531840 MD5sum: d521f057c7a0f9f0eebd32ca268a6cac SHA1: bc6a859c6a007d16dce0ec422f53b8d633166cb2 SHA256: 482e9ee9d04b1483554e2446560806c2457cf54cfc4bf1ca80afe739d266af96 SHA512: e16c806cb285f131acefbe1ae311d2e470ebc1803301e6540eb1783dc7014911351d6956db912fac644771d5d7d079727252e628e199a94616a5faf2c11f7430 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12270 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-mqtt_1.0.0~alpha.6-1_armel.deb Size: 2614108 MD5sum: 90b4ed6ffa280f874facaabd57345617 SHA1: 064dba437d6dc8e1b8c7d3de2738c32c6c924497 SHA256: 4b55a6cd1ece927d1b0482c3cc22eed3866b4c11cfc00d15e02b2a79995a0a88 SHA512: 45e816910690c4d6bf6ef0f0eab5692b188d0d119be01a8d1d1fecf87a8356df2ef28e48bf60ea2c97d6ec3a8d3bb63d52de3447193adf4ad83c15538bfd776e 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12186 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-mqtt_1.0.0~alpha.6-1_armhf.deb Size: 2657032 MD5sum: b78eaf851477884786b32e0ff715f722 SHA1: c09abd6d3fbf1f629d8663b76b33d30a6c3aa336 SHA256: 12b81f54d10f5dbcb644920a3c2b5fcbf12baf9ce0d2b073d5782b3ce3c981ff SHA512: 6ce2178018e53e51b0d3790529fac34d9760d0d769c79d20aa9477f788eed4af7e2014eeed3392670ff4f7da5190b519ab67ccef0e0a11cdd50d9ca84e492822 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-rest Architecture: amd64 Version: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11604 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-rest_1.0.0~alpha.6-1_amd64.deb Size: 2208468 MD5sum: 2a2a0be87056ae5081c09d66b1c016cf SHA1: 6cfafc61204ed34704e2f4bfef2fb778d2d717a6 SHA256: f0281dceeebc5970d803cb9c1ac929f40202d0c5d5c0b515c891d0ed26026292 SHA512: 8f9d7cd29950f40c454ee9957a0bedbf17aecd81a5612e0e28658164fa4e33385cbb0be53fbb78318f10f0e948cbfd7b2ecaf969000e00538735e33d875ebf46 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10413 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-rest_1.0.0~alpha.6-1_arm64.deb Size: 2003448 MD5sum: 3edf3417e499c413e7b7994194e4683d SHA1: 5a561939e13f82e5cb01bd8a9fcc928c3bdd433b SHA256: 33ba99a9cdeacd969054c4fe0cbaeb7f0a0f220fc1f9ee00d946f81ae148cf32 SHA512: c11c4aad01a3f7a9fdebe771111b537e3ddd809d05e6cd68a1e05e351443a433012ad9b351f506227b6676d20ba8abf5b1555a9a08b034d559ae0c4270417ec1 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8589 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-rest_1.0.0~alpha.6-1_armel.deb Size: 1877728 MD5sum: 417bef095eb7521d59a6b0f02cdc56f6 SHA1: f2b072082bb46ae25fd4ea5bb0c8bcca9992160e SHA256: 9ef885f19c356d6df5a5e386e79de5475f5a7e9bdbb4f7122a05535aa758b0ce SHA512: af3a3552e514c5f3212b60310c9930053fc2b39a3e908bd3cf84920b1709ffab893dcf027173b91a3b3e9119f26a8a0617bc72272ddacfea6228347dca7e402d 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8468 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-rest_1.0.0~alpha.6-1_armhf.deb Size: 1866352 MD5sum: 49e25fc1789b46cf81b632519abee7e7 SHA1: f36b99acba9ccc8b69d213bf8c27200cb56872e2 SHA256: f0256327ce01a780d71c4d04dd0b4cea50f488c96a6ef3026b145d6787eb826a SHA512: fb57c618d86c8ea48dbffbde7365498e4313173a933c1eea5d0c3a355fdd302d69b016e55caaddf5aebb709ff2c84be0a1be72c0eac3ea6b8914ba1c3529ae2f 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15218 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-ros1_1.0.0~alpha.6-1_amd64.deb Size: 3143360 MD5sum: b19d840015020062f8018996bc687b9c SHA1: f6cb669cd2227500016bb0495885cc4fe408f79a SHA256: fef96823404fcaac97932055acf19967f9e57e54400aaf2ab021239564833fb3 SHA512: f0630157bbb7e35f7e43e1ea21273650dbfe1306f79b348c95d9d8999b7ee570282a2db182f64cb6725114679d0dc578657423edfb3b3eb3d04c3c4e10ec5a79 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13880 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-ros1_1.0.0~alpha.6-1_arm64.deb Size: 2893864 MD5sum: e7af128ed83c54157b4d4f85dee65955 SHA1: db01753080dd74fc539f0b5c827988c895ab8b89 SHA256: 7218505042f1dbb19cf0dbb4b9d8442b8fdad22d922f633fe5c1a5394979410e SHA512: d71dd771d0bcb1e51c9faab8b313a98c58f60399ff5c7bbf63c6aafb407b836223d79059eae5000ea6326d7eb950bbca5be58014ff432a65958c43a317e11733 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12071 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-ros1_1.0.0~alpha.6-1_armel.deb Size: 2795032 MD5sum: 7397f827a9793c6ac0a2a57f8e7c3682 SHA1: 81b50dcb83a0dc65391f8da7856c301c24b03de6 SHA256: 382b4e312e68e6b20ac1c0f1d5cafe58c52381ee670be74740b862fd6a208bb9 SHA512: 33a1293e6ba750e2aac5601adf32d026ae55068bd1da05d85e0f4bf9a9631b44055161c47f9444cf692d426d9135671efa653357dc17200381b5a554655b9e75 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11855 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-ros1_1.0.0~alpha.6-1_armhf.deb Size: 2768812 MD5sum: 0dcf7f81488371604dc05e0b8714bbf0 SHA1: e4888623be818298ef1c5f034bc26665bc421fb0 SHA256: f1f2a71aafc65dee8d6c2b3809ade6899e20051112a23569eb1b88b1df42a57f SHA512: 297be1cf5e3bafd4e0523bb629e5a9c7b7448dbedcd02c3faf91d9f288ac323d847777887d2221c7dd0e114f097f67253a7b213f3c2a09230032638fdc0aba1b 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13234 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-ros2dds_1.0.0~alpha.6-1_amd64.deb Size: 2645072 MD5sum: f3ee7aa4f34e079f56a30503724ca52d SHA1: b5a5465a971a07633fc0cc89d7f8f45be17760ae SHA256: 632d0d54906998e9d858f444e25aae560ab97d189794a028040a88f1e2628e0d SHA512: dd9218eaed1572fbfdfdcaf91d9e0bfe45b0cf1a44046dd7ed743e6a503dbdf96e40a49b7390e894ae9e41b730adeca09e42559fc8e86e434587e92809ef112e 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 described 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 maintaining 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 architecture 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 possible 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 bridge, 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12007 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-ros2dds_1.0.0~alpha.6-1_arm64.deb Size: 2408948 MD5sum: fe5ee5d936f14ba9f9f14f6394dadbce SHA1: c3bdc17823feba87a58db7f97db99f29313cb07c SHA256: 95a8fe469543e455679abdb29446fb64a42cccda0964d78590f6d7bce03a88cd SHA512: a6d648ed2ba0d7408c9c45bd1c4bc374c5e7078d9dc9ce1bfd8ee6933e19c4d6cba9a5137796822072a3e7641f31761695f4051b682b08172a6c7d6fa07fb0cc 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 described 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 maintaining 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 architecture 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 possible 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 bridge, 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10063 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-ros2dds_1.0.0~alpha.6-1_armel.deb Size: 2275320 MD5sum: fecea1c2c07e6710231899c2d6a42dcd SHA1: bf10b5d8ef8295f35c81727f5e3b54216ba4b98b SHA256: 4c5e8e69d1f642c2e596c9d11b7f35bba8194b921704e2e8156634703471fd57 SHA512: 07bc18e8507f38b49fbeb596cbb19b3bc3a1897d9df2033c5e5bd12b7ea8f44d5ac7fd200c9e444bf9784f2880ea6f9c9f8c69e73cf03979da97a6eb1545955c 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 described 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 maintaining 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 architecture 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 possible 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 bridge, 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9688 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-ros2dds_1.0.0~alpha.6-1_armhf.deb Size: 2285728 MD5sum: c077f5e444600ef27af9c489a72aa9da SHA1: a7d2e2d04b4df7a66c4429b073dd22ce0397090c SHA256: 2c410fcf48cb5ba63aaadf6119635ac9ccaaa943258b70364525aa48e00b1d10 SHA512: e08edd4486e9d6692b9202946267c830998fd9431534a524d265037a6144d40cf70844691f7f6c552e4d28d1ea6fc6856a16e7a6858eae501d99a4442e7ea1ce 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 described 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 maintaining 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 architecture 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 possible 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 bridge, 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11722 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-storage-manager_1.0.0~alpha.6-1_amd64.deb Size: 2212776 MD5sum: 4a557e202aa439be569d182bf2e6e928 SHA1: 90ccb2c8f2057daa5f32ce27ac9c6f94d2320fb9 SHA256: 0d3b7d45f752ad58f398fa659af4f94744c3ab3f651e0746a52a95c7a9db0ce2 SHA512: af0b646e350b99e60718cca2470b2dc0dff832e186400a4353c2e91e62fb1e761572cd5177b9830e4874b615b4c6c46e5e711691fc78dad99752ea2bbaeead43 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10483 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-storage-manager_1.0.0~alpha.6-1_arm64.deb Size: 2000360 MD5sum: 20fb730b1ffd6273c613ac6551519f4b SHA1: e2a992d6dfa04b499afd3418bbe1c4e673efcd11 SHA256: 62145e8432930a5d5cf0eeea9b6c773c7f5405ce76f1d3677dd3f7e11a37dca8 SHA512: a97f120c87d7b8f699daa044f2da9adb5528b58d9c291ce1ba6bd9952258a9496e8b4ca2360853290ed0e0e4bdc44d543e7c5565ad03d2ea1160e306b7e1d710 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8712 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-storage-manager_1.0.0~alpha.6-1_armel.deb Size: 1901228 MD5sum: 5c9b6fcdf1359be5cae219dda0252341 SHA1: 3245c3cce8ca7736611ffb4b7364175b6c060e85 SHA256: 1c84d8ed4c147e6330577e4568ef18745a7bd87ea5a6e56438ff98f83ba826c7 SHA512: 9eb29d771275dfb4d6b753e25a8d7bc4658bdf1872c2252805c45c9055f59d53b46eba6cd356dfae12adce49654197e17e545dcc4e718ae68eada43e2f77b54e 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8587 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-storage-manager_1.0.0~alpha.6-1_armhf.deb Size: 1892344 MD5sum: 7bb9a3d0c42f8a1e09518e1a9f9e0812 SHA1: fcba9b47f0dae0cdc1daeba26f9a8fa18652a5c9 SHA256: 8ce6085b2fb25166b56f2a5b2f8a942412a93b3f3e26a33d75a5725233118652 SHA512: 4edb686842d07f3b0bf7f67bad46f806246e63b0000ab15973fa5bc88bd064fdb836545a7071d7fd744ab326de726c63c5543db49eb0a3baabb12c3eff040797 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14065 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-webserver_1.0.0~alpha.6-1_amd64.deb Size: 2656784 MD5sum: 916870bb6a0b911f683a75a2c5e60247 SHA1: ff529110fffd8a024d7e67a7212de8ca3e385bf8 SHA256: 63d87c198478d00ec5359ba8ad54c46aab57e5c8c59813dc880d3da730a273e4 SHA512: ef5db1b39f10e4e9401d385cd336f6fcffdb3547ee0633b0f315c4fd1adeda160ea3d37a113eea363d4ac01c4b33284bae109e105e195ef297e9e677161059b9 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13146 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-webserver_1.0.0~alpha.6-1_arm64.deb Size: 2454960 MD5sum: a837f886b3418a7d8b99db20e04ad076 SHA1: 5b77182f3bfc493743f8a6f7b859809c5b88bb5d SHA256: 2c0d4468912c0456a44ecb9da4c458decdecd1f3bf2f2409c329518cc087e99b SHA512: c120c6bdb5c4b87e3ccdcad93ebdbf98fa22f667fcb4ddbccd0e0ed7ec98800936c7717b307fe022fda7d657ecfc9eaa024b220f7d14559806f6fe8540336968 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10865 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-webserver_1.0.0~alpha.6-1_armel.deb Size: 2254988 MD5sum: 8fc3db88fb3567a36e694decd4b897a1 SHA1: 4a11dee9897790d55540f49cf29a400a718e4638 SHA256: 36625488973a379d27a432923c375b238321ca3f75057dc8b05f7ab84be05ce8 SHA512: 01c7b776b359cb95fae15ec267abb6e6b19815ad89b1af477d609a11d6229bce38dc40bfac2ded31fa57bbd2ce8d28d476e1f755aef1a4ce0a3fa8ecd8a9dd21 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10714 Depends: zenohd (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh-plugin-webserver_1.0.0~alpha.6-1_armhf.deb Size: 2236724 MD5sum: ad25d521aed1cd289d2eb5c454ff7184 SHA1: e08b9566318d863d851c3effc1130ad7cae18e10 SHA256: c90d33ca797752ef370f918643d9dd1da283ab94f0d52bc18b43128c194e754f SHA512: 1260f1a5a79abc7f8a3f0cdfef5cd15e1857f7ec7a907d3328ed76bd0dded4c778749cad03971f360cba30bb137ffac0598c33f405dab6ba7687a23c6d9d6e3a 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.0~alpha.6-1), zenohd (=1.0.0~alpha.6-1), zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh_1.0.0~alpha.6-1_amd64.deb Size: 17312 MD5sum: 08e1ba50112f14f81351de4f99f4cac7 SHA1: 13d1a5ecda7d1b5cdcc1b888ce16c21c84491c4b SHA256: cbe4c85b762151f6b9ae16dabf840c48acaa2e6f8322a02dc66b3053bad8e139 SHA512: 3f844067d9733ed18454d4149d0d97a517bc4c9e1c5a1b2688e339efdac93a6189c16dbc212bb3c9ba40aad3cf68cc3907d620490d2ae6648515914b3d1a94d3 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~alpha.6-1), zenoh-plugin-rest (=1.0.0~alpha.6-1), zenoh-plugin-storage-manager (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh_1.0.0~alpha.6-1_arm64.deb Size: 17312 MD5sum: 6e6bd764b44a6be971d85adcd2ff4479 SHA1: 983efcd80b7337248ee023d75eb3f9f99eab6e78 SHA256: f67065aee64d0a6312d838799fe5b49d170b4358cc4e52190fbfc8590802fcd7 SHA512: 315222236aa0409dd0e7fc1a32deae8c17f9b51bc8cf751be147086a281708639fac2f80b752751cb5fed4d14e826346b36a6179e0c06faa1e4c1993f05ac5c9 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1), zenohd (=1.0.0~alpha.6-1), zenoh-plugin-rest (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh_1.0.0~alpha.6-1_armel.deb Size: 17312 MD5sum: 84856f6831ff788e2fcd8f103c97c0da SHA1: 75fe980676ab6d4718e10897dc1dd2b21c2a6a28 SHA256: fd87fc9fa30721156c13bb0bed60c3f1e1f5f37c8b3999313f8f59f22cd1ba47 SHA512: b6ce936b66bb540b4a6132bf9e28af35678b45c9d562e2ec888daee4951aaa85d501cf00b687f992d531b9e1e3a181948af3b6efe68ff332b7b27bb158ee9103 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~alpha.6-1), zenohd (=1.0.0~alpha.6-1), zenoh-plugin-rest (=1.0.0~alpha.6-1) Filename: ./1.0.0-alpha.6/zenoh_1.0.0~alpha.6-1_armhf.deb Size: 17316 MD5sum: 3b18f1484e2d734902086a1a41046858 SHA1: dcbddc57fa998a4b0b02d7b12f348eb101917982 SHA256: 95d1fa98ad7d816d610172b96ec22be7444bedaf9cbab2b386a93430e0a84d32 SHA512: 55a3c32d1af4b5593a8e5413ba98403886cdb61d8ed8f294daa7078a078d4ee507cfdf38aa20615957826cc93f3ac9e0139c9ca0d583f77630c2e4baa64a230b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18565 Depends: libc6 (>= 2.29) Filename: ./1.0.0-alpha.6/zenohd_1.0.0~alpha.6-1_amd64.deb Size: 4515008 MD5sum: 7b3e920c6a467350fd13cb2060b25b22 SHA1: d479b241ef14f2882458b614200c3d98edb3e2d0 SHA256: ce7fa31b8636a3b09cb04d8caf0912ab6e5e814a8001984282361bea7d2f138f SHA512: d042d30aed49938e7f3df7787f8841421c920c4814a213359227cbf96efab3eba0344c7d162536a69281a1089693cf7be11d09af8e8da42a318a8a90c07b59ec Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16489 Depends: Filename: ./1.0.0-alpha.6/zenohd_1.0.0~alpha.6-1_arm64.deb Size: 4045800 MD5sum: 82aeb8cbf1cd11d2d91d668a1a7df076 SHA1: f2f8fc37a11950ca24eead8474f8b9c9a18a3b55 SHA256: 5d6f24dbc88a9d540250f977f888e106d6208afcc882d36b66552e414136a09a SHA512: 67fc55f60522b18beeb9e4dc74ab3997e86f58484f530652d8c0724c0deb31e13f000e0f32a50179f7b820abaac289470a64394a77596bafc8ab5c58a0b770ad Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17937 Depends: Filename: ./1.0.0-alpha.6/zenohd_1.0.0~alpha.6-1_armel.deb Size: 4388996 MD5sum: 77db375b7ec8f57adb232fcc2c193e98 SHA1: e1483106106ae786eb070e37d70bc18d30924a68 SHA256: 1872658002f040b4e3d679e7416005979c343c3527435f7c717b51f63d2a1483 SHA512: 548381631e5052c7624eae7eaf79ad3e50618a7f38bfd43e512c232e190ed15444f0a6c3550b657a65aa3b1e740b0e61d5e00383b8e7794a16b6cdc088ce80df Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~alpha.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17706 Depends: Filename: ./1.0.0-alpha.6/zenohd_1.0.0~alpha.6-1_armhf.deb Size: 4441112 MD5sum: d90a27a8dcb7b59a59e80d0524861215 SHA1: df27b6ab1327df4592ebff63e5628e8a588b65c7 SHA256: e01ccbc4195cba5302d4319894a15c485b9e6cc1577c7913a931229537bf0a7d SHA512: c459c51acca70bf0d6e7bf796610877b6343f900c7301dd8cd5a17e55e504de46c64361c0b70b58fc872cf384cd0387d6c63e36e4f5429521d440cd8de670832 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20768 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-filesystem_1.0.0~beta.1-1_amd64.deb Size: 4586748 MD5sum: b284abe9e15196064227e4e54930f5e0 SHA1: 633eeb909f51e3b71bca51f257f9d3656014e6c4 SHA256: a8c00cf11ab171be011f727bc7a4f142aeb059cc73d1a8e58741c0fb05565cb6 SHA512: 61015b43376184e7bb8803fb7e613d8d6137228db865160e06084ad5b79ccd74f6faa603f1ed77f2d650aec658ece1c9385fa1653f3cab94f44e23f0a8fa82e0 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18890 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-filesystem_1.0.0~beta.1-1_arm64.deb Size: 4123532 MD5sum: e7dcd1d6b305ee81891e4dd6f1f5f34b SHA1: 56fcce4bff44ef55c7a9079f86d1b69108eef097 SHA256: 1851612d8203f40489c1df9470ac35f2f98db1517151ae638e2b4c311e76ff83 SHA512: 1793bdb19053c359c08e3c64df1b2b543f0beb962d34eac05a41f714957a24f6a6188c4d0c59dfb0d4d5bbc67fa1a4b36732d1b37302663fbdb90e03ec0877e8 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16490 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-filesystem_1.0.0~beta.1-1_armel.deb Size: 3908464 MD5sum: af5e40169478bc81d6b091dba84f68c0 SHA1: 27ae66d5d5e93c22d10a51f8e58b551f45602af8 SHA256: 6b683ebadfb666aacad65ee4e5873c926b2291166c90846195f12cfc5b53891e SHA512: 5820f25c68146f545be56b4abbb82bf38e89850a40f91a017bc87885bf702c79c743daedd0804e44c0a159df7c95f5be449121f86f5754c758b8b352b56f8be1 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14613 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-filesystem_1.0.0~beta.1-1_armhf.deb Size: 4003096 MD5sum: 2c5f4fad592f6bb0dde65fd45b5e616b SHA1: c148c554de49cbe450f490c9b058f656c70aa70d SHA256: e9623b21ca810e1af1a849119f000756ed2ddbbaeec209c0fae9ce4c84fb3e2c SHA512: cf74ff97c100dec85248e5bd8aa6af1d42a289628510e001d91e6aa1c1325f5faecec4f8646f2b0e738c16e02edee212a96f85179b204c451a95c1743d7827ad 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15587 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-influxdb-v1_1.0.0~beta.1-1_amd64.deb Size: 3096892 MD5sum: a681c445aa50fe17561a315563b366bb SHA1: 7e3ea23090fb4caa90a4a389b508b11aac9e2279 SHA256: a3ef4d0652cbccd758bef49c3be86dcdf442e26e4198da20a991c292b798f1d6 SHA512: fb8c0aa7f7e5baad5148a00360e5225d87802ce8fc8f4565e2266e61eaa1ab2d364ad5bfa6a4a7e7f746296e2419f904991a35920e4fe4e2dab10aece1fcb8ec 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13914 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-influxdb-v1_1.0.0~beta.1-1_arm64.deb Size: 2779020 MD5sum: 07a1a864729229b48c57ad9937685286 SHA1: 065fba2d60c8f414c97a76ae4ed5bbf26e212783 SHA256: 782f22ce9e609c982bec93037f3647872a50ae0abc82cc6ad8a5e61948fe5913 SHA512: 9edcc81c13f09f7aa06d23608161ca1eaeaf5b6d28d9f7491687fd1980258d3b4f89fd0176a15602dab802e6024e00be0e99d9819e137b2f000b2546359c31b8 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11738 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-influxdb-v1_1.0.0~beta.1-1_armel.deb Size: 2534532 MD5sum: 3d3c3a7bad9f3d3994ca01da1de38194 SHA1: 86d30f6d03ba4604d4a479fa3a7a66c635e82261 SHA256: 980986f846b209dc1df0dea1182c440d982cdebeaa17b07211503d375deb0dea SHA512: 059085dfd58a248d6c6e852e3109ad067b9dea223ebc236a87eef94ae95acd3e6588fe90937f0ebb7c4cc9b60504577c83fa8bab3ba63b4f67f14c420c95ccb7 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11615 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-influxdb-v1_1.0.0~beta.1-1_armhf.deb Size: 2524524 MD5sum: 63038c301b2b49798afb6e6834a690b8 SHA1: 8a42852ddf0b101cffd118d56d6b6f7f99dfb5a4 SHA256: b5b20f1275c1d149b159287e8698599ea651a7702924be9ac5b70cc7f90ad406 SHA512: dd31e520e416eefd16642d15d904c1c47e8db8885a958ce7e7c985289e1944d53c5f2b4ad4905082dc48c232accd80dc8764a38c0458a8009ad7524886ce2d81 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17067 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-influxdb-v2_1.0.0~beta.1-1_amd64.deb Size: 3758564 MD5sum: 40e81a8bd1ff18443e478c7430c2a9b2 SHA1: 9030d6d5618d55b26383c125d423068d3583f4b0 SHA256: 2364f39747b18e54d0913780eedd3aceaa04f8985db2719d3649afdaf2e24ae8 SHA512: 631029da1a76a828980934d7ad1ddc71949936daa917a2d953b31683c58db76eb473f2b1ec69a5a6082053f62852d4b881d008e2058dc14603ea1bd483c6e4cc 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16050 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-influxdb-v2_1.0.0~beta.1-1_arm64.deb Size: 3441204 MD5sum: 45fcf212ec58a3be3d2e3a29377db1e8 SHA1: 22872ebac1628c63f9193c1bf6ff690b55ffc832 SHA256: d5e24e54c09a77c2d083bdf4ab80729aad5e8a7532f33d61c272b6102ec6c2f8 SHA512: 35c04965e6a5de63f90f5e78012ccb7712ad91c90f31f1d6d74a3c666ebee0482bf610b2ddee2f753b7ebe0aae7b902dff9a925e0f239a338575eb5614b71475 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15341 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-influxdb-v2_1.0.0~beta.1-1_armel.deb Size: 3421256 MD5sum: 30f759b99abbffe343f07704bf2a380f SHA1: 28968249019f0fea1eead16d5b6a621345c38e9f SHA256: 3c8b8f8b03c214d9ce4a9b0b1e1eb4d4f46eec32116da3be6fa91cef9ceb790b SHA512: 95e42f4511af04127c461ce69ebd2892c8a4c93afd1b052bd4520b7ad0ebc87a794d637056b4f62d1e8edc83e337a8db046db2df099d850aff7b7dd44348c815 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15240 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-influxdb-v2_1.0.0~beta.1-1_armhf.deb Size: 3470016 MD5sum: 578afe84b3f639c7b5474006e16aa652 SHA1: dc617a156d3725ec7e6dc79ccc49e613d2888bbc SHA256: 5c81dfbf8b324eb17a5895c9331da1698a2481a5b205c4766daef8c6f3000c27 SHA512: 89acea48f4ddfeba49a55478beda69a5b411051408518c2d886528451e800e6b64a796a9474b85817262a42719e5d148802000d92200645e20a62c445cce4ac0 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20390 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-rocksdb_1.0.0~beta.1-1_amd64.deb Size: 4534180 MD5sum: 959095253707a76a98ae6ddbc065db91 SHA1: cec9ab677c474ad98d85cfc852e7d6b634d5d2c9 SHA256: 8691a32b9c183037a7f09c9418219bf7d4529248c952ea7fe096dd82cfa6812a SHA512: cc72f5e8d04bcd3465444c4b3ceac06d0909e1dae3c09cc88fbd1792b1f912f696f4e549c8aab96d1cf55ce09e4d680521cb0a3e970a548e223e383002977f82 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18391 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-rocksdb_1.0.0~beta.1-1_arm64.deb Size: 4057632 MD5sum: ab6535def00e5bd6dad0ba5e04f1dcd1 SHA1: 06af578be2d50390948e51c269494d03595d8fe6 SHA256: fe84ee104f7da5b905091a677400067b5ad46b324cdd65f6e4fff3967e90f0a0 SHA512: 654f783b008805440b7710833df391e2ac17850610765fb83080369ee43867f2a944e47f38195f530ffdbf7068731cacbac0dfd4cdf7ad04ad773fc41bc25ddf 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16146 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-rocksdb_1.0.0~beta.1-1_armel.deb Size: 3860108 MD5sum: 9c8492d95cb6df4853069ff385bd5887 SHA1: 422f5bd6b3b9743e87b3225973ae484d6173dde8 SHA256: 1284eecc0b838b43143c00f740a51696527ef0ef8e606e006a3aa43d102be680 SHA512: b9c7091db002a765324e4dd6636e2da3f7212f3196f13ea0990f00a5455430506dc3ef75112bbe74b1dc1ef1c3aa7243e6e5731d2ab5c2b3eae3da68f36a46b8 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14223 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-rocksdb_1.0.0~beta.1-1_armhf.deb Size: 3953892 MD5sum: 7805d0294d8ce6f7762c201380efc4b8 SHA1: 4344f86dfa70ec6aee43583e9a6c402b4c0a8423 SHA256: 64b9b080779ce3c217bc17661ef4a0d31e5d024e2f97acd580d17ed3670dded7 SHA512: 6f434c395668397106783c683d8f9608ebbd8a56c71a92dd6a7b5b4cd6fb356f81dab8adcea22fd7fb6afc754476d589f50b972c5b44a119154a188c88335628 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27188 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-s3_1.0.0~beta.1-1_amd64.deb Size: 5494992 MD5sum: 4111ad133c9221b3205a6ab10acb3277 SHA1: 9f0bf99ee87e816a1876a9b76a8b39bedb9f1fb4 SHA256: db41c106bf3090da3a0598b38e1969a1e7ecb96c263cb27538ddc5b35334eac1 SHA512: 5cb6746810e86db65e182af11ff4d25a6f8bc54c191ead65a3a566adfe8066a7a1917b161a4902a7a017b1626b464aaccb07a1115d3884b2ae880619d7f222e7 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26388 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-s3_1.0.0~beta.1-1_arm64.deb Size: 5208460 MD5sum: 9ffa17b6a92c658fa974afab426b948b SHA1: d55ae2e2aedd23454a5d770163a18e452d89f7b3 SHA256: 3d7720917f911c612a7c214fc90564d1e1c44170ff38f5e2d6e2fb564415e656 SHA512: c7f7db849277cb144bb60a8e33b9c6313f6a4a1a16d88bcf7a0ce0d71340686a6e8b250521ce6350f0b32f5edc5059ae6a82a8ef475f96ce15159dad7d0bb285 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25239 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-s3_1.0.0~beta.1-1_armel.deb Size: 5098156 MD5sum: 6ce696c73505f98bd926c1f0d8aa066e SHA1: e1dae496bf961059791dc405bd3ba798c0a96ec8 SHA256: 2b13c077b014ee448e54f99d73a94c0bb49ff5ce53ca759d96168a5ce7a45401 SHA512: 43c21cc7781ea484fae7f5a52da63b36d3b78d581449b23114326ddc53965cf6215c507a5699228b95c359ec771d430397dfe969e435fe0c28eea87bd611252f 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24985 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-backend-s3_1.0.0~beta.1-1_armhf.deb Size: 5131820 MD5sum: 849d626b61d9e5c98457320969b772f9 SHA1: 848c91122badd2d77da569e1430fb4337d5140c9 SHA256: d738d04f9bc3d3c188cd56955e121a58d2a6cf0e48d94b1e4c98abfba3615f25 SHA512: f1a85e43d73e9b0530fbc04808901348418f10f5931097afa7ea3aaedfbd68f73a5f610579d80b2e401b13573f06265b61bd1f4a62d311c15820a0c2c1887106 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21155 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.1/zenoh-bridge-dds_1.0.0~beta.1-1_amd64.deb Size: 5318524 MD5sum: 8c2a835fbeea05de8e12868713f9b325 SHA1: fba9bc45006f394bfb31e3124882b38c5765681f SHA256: bb95e0d3b7798edf94cdb2787bc72f60bc05cd818f0acc35265c964c70629a87 SHA512: fad6b5533e103da922ac3ec9a8b92a7381f22c387ce2bf951690286b3d3ebc97eac73bf2dd28c1776f7f620af2212538747abea57a095b1cb913f735d9a7e0de 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19248 Depends: Filename: ./1.0.0-beta.1/zenoh-bridge-dds_1.0.0~beta.1-1_arm64.deb Size: 4791088 MD5sum: 5fbdc754bdc1a6ce7b14d95f196dd443 SHA1: 094a0cf016aca16d713847622871c4622002f970 SHA256: a9f314f823713b2d812357e69a714f2b2859d9f1223cdeef8d9d598248174f9a SHA512: 9369d238bc2f7967a386330050ee3212b643a1c17fa62dafca9fea64f15072b1168e36a1a20937b241bd5e7426f77467105e998e6bed4e435e13e8edef8c2185 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20516 Depends: Filename: ./1.0.0-beta.1/zenoh-bridge-dds_1.0.0~beta.1-1_armel.deb Size: 5085628 MD5sum: aabee008bec775aa3740e008781531d3 SHA1: a1b04eb0b97c07126a68d317256d8cb7653546f5 SHA256: 291a909412851cb3dc3d5c80347ebf4f0696dbef8285743dbe6b97caed610970 SHA512: bb2bce09880ffdbf35c57f9c74632a57d3e8457e273ad084fdc1a6d17020a6466b54b01717ae27ae3f802ed7513b5aefa51c04870af480cec2071de42e2ab614 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20010 Depends: Filename: ./1.0.0-beta.1/zenoh-bridge-dds_1.0.0~beta.1-1_armhf.deb Size: 5137136 MD5sum: 738ce7b441ef9841938d255dfcec3b21 SHA1: 330f7bff7f603b8550f09204aa14321fbab738d8 SHA256: 31c372ba91be9aa6923dd03f840d77f99edbe03eb13841f5a71d04f355c9ff81 SHA512: 332cee87ca87dc526a08f8be539be7e2851da364421ed43739d2b52c693a7ec56c8dc343d3b22c12bf350a6ae0f0d3ebcc4518ebbe355d36f2f07188128cf3fc 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20909 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.1/zenoh-bridge-mqtt_1.0.0~beta.1-1_amd64.deb Size: 5081892 MD5sum: 2830a2e942c8dce3ed4648eb2113bffd SHA1: e87b4f67e84d1342b13f8f59ba578f41d06ece00 SHA256: 7cec58e940dad0fe5f6e2997b33cc5ee8d1fa1f37ce1efc3083920ec59e9d82d SHA512: 4c8e62154f79789315635fa12ab6613225241433dc005cdf8dff7c77785f601247154f0b11e252c4a37d8a76c1d38ad96edb175837f42560fc453905d91b3853 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18970 Depends: Filename: ./1.0.0-beta.1/zenoh-bridge-mqtt_1.0.0~beta.1-1_arm64.deb Size: 4585276 MD5sum: 04f9170f34b628fbd2ba52e098544afc SHA1: 4a88eb56103243c0309818b5946457b29c3f2f93 SHA256: 2d3390337dbb59a7a508dcc8344fc24e345c1ca2946e423d65e529396ffdab26 SHA512: 7e369d94f794b6d9444b6bf9a1d2f24300544d610b3eceac78a178e9209cca1530aefbe1b4e5798e1cb561bf61584bbde2c2e2c4ef27bc207a1cf7ad86c2e4ec 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20436 Depends: Filename: ./1.0.0-beta.1/zenoh-bridge-mqtt_1.0.0~beta.1-1_armel.deb Size: 4896932 MD5sum: 9c8754990d10748ddb845b19b4cf6a84 SHA1: 2321a7e8f4074979f354e4068e8e62e3fce7b6fb SHA256: 702967b460938322f4168a11ce0c83f81c6265e1ea2ec0e048d922483ebcb762 SHA512: cd5823ba0fbdb31c898691ba8abb335c6d2a0bd0db364135220b34c615c684099d63797b56c9bdb7a412de89186dfd133c9c473132428bf3f78cd3b54d638e1b 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20175 Depends: Filename: ./1.0.0-beta.1/zenoh-bridge-mqtt_1.0.0~beta.1-1_armhf.deb Size: 4926368 MD5sum: 77206bd9d1491f085c7dde515642cfd5 SHA1: f920cfe40dc0cc330da069a150cc5496b399f268 SHA256: f3f71e168b00e07a63678406adcc116a7e991cc3d35336c838e03bbf068c152b SHA512: c53ed608cd1068c9595ef491e0b438e89e9c30a95bdc8c57e5caf2ae25d6d6e48090578e0351067435949aa37ad6d05c322da501b33aa405abc57b8095b9f6eb 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 22250 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.1/zenoh-bridge-ros1_1.0.0~beta.1-1_amd64.deb Size: 5406164 MD5sum: c80f60d1d4a4c4064be2b58953bf4172 SHA1: 03f1f34541b6f6d27b30a7bc4245e5936df65337 SHA256: e3c127e291ba1336a065e793ab52285e7f3a3b5d1524d98fd6597e050d87aada SHA512: a834aa6a9bdc09ee520396ffb6c75e00688d38cc1492b5d8044398c6613ed680a1a4d505b896234e1854e62068b691fe2576ef09f1c165141a3c6a55f4af6dd9 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20230 Depends: Filename: ./1.0.0-beta.1/zenoh-bridge-ros1_1.0.0~beta.1-1_arm64.deb Size: 4867992 MD5sum: 5db11c6ceff60e94db3b7f412f902963 SHA1: bb3584fb5b3ddf917539886bd27e040bdf9b53b0 SHA256: 7da2dcdba6c163c48b15be41ad05e02486581a42438eabd77fe902a7b0941c48 SHA512: 7ada847e1d096e9b4ca02d33e535eed75971928fefc58222eeba80cc29b62cb1d840895735f20029f01077687a31e179c1b4042f03c3ae5bcadd461d0ae2b96b 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21679 Depends: Filename: ./1.0.0-beta.1/zenoh-bridge-ros1_1.0.0~beta.1-1_armel.deb Size: 5218636 MD5sum: 1b5f8b23e072301629d0b7e7ca8b95cb SHA1: 1e8efc0506023bbdd075cc11131fa9aed136497c SHA256: e8ea9c540c898de925a18fe5ceb587c5771630782faa0aedaee6e46c22457e3d SHA512: 39dc7e1c4073f13b0f036b7ecd848b9819543b192ba52838dbe3f27734435c60f915f732587961007716d5bc81547df26c823358d559f3300a2c733c47e5911c 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21369 Depends: Filename: ./1.0.0-beta.1/zenoh-bridge-ros1_1.0.0~beta.1-1_armhf.deb Size: 5241420 MD5sum: a39c6a440218ec9b6b482cc6b20ac970 SHA1: 39f3e1f89a6a16badf80096e91fa6a243dea2610 SHA256: 48eb926249aef5121d91a143ea553775f5f33d3a8d3c23ca2718665b57c8dd88 SHA512: 2298c4ca4e6c6e74b5a538d733f8eb46bf38c4e59a846ceb2e2c0bcadfc26022a9b86274a203184319e1e59e69bcc39a3ce53b9eca680f7c1ad317b9a6831bbf 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21720 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.1/zenoh-bridge-ros2dds_1.0.0~beta.1-1_amd64.deb Size: 5419668 MD5sum: b95d1556a6fb2955885eab5787835286 SHA1: d235f7759eab06a7eb1baa423117bd1e613e43b6 SHA256: cc9866b05c9c8c53849a1bfe6ce2226e8050e65e2aae00fc29708026e3297df3 SHA512: bd73a7f964567fe999e91bc4fbd4907df5eafe6296ebef76fffe8ed66235674faab18c29c0e210750e761a8cfd6de83e44658d9037859c6f6509979807302582 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19788 Depends: Filename: ./1.0.0-beta.1/zenoh-bridge-ros2dds_1.0.0~beta.1-1_arm64.deb Size: 4904608 MD5sum: 56278c62ec667a072c1fabe1a03ad2f8 SHA1: ef955e9efa6894cacd147528276b04243cfbfcd5 SHA256: 2a45cedec263b539b078c77c573859a11a48a37d54103ead53b562914cc02688 SHA512: e920c4f5c8461eaae55f48b2cac7ba71d3151af273dee30e4080f14ee594f7d6deeb10ac88c536d9f84608208e9b1620455aafcc79049ff0100eaed60e85c955 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21064 Depends: Filename: ./1.0.0-beta.1/zenoh-bridge-ros2dds_1.0.0~beta.1-1_armel.deb Size: 5194896 MD5sum: f84c2d8b71dca98c28da61a9fc805839 SHA1: 3c3bb523323de660ebde0f63be17802472ca81e9 SHA256: bbbaf6b23bc3bbb9149806bc197f76ffe5f3b9dd485195b3da9aa4960060a231 SHA512: 8b1fe8f70680dbc8b00226d4b15060131a627546090786d736299ad647c7737530c2481dbcfc73aa41b0f2885cc2aeb067d12b28f9c8409ec4b4bac6b464b426 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20564 Depends: Filename: ./1.0.0-beta.1/zenoh-bridge-ros2dds_1.0.0~beta.1-1_armhf.deb Size: 5251664 MD5sum: eaa7fc0998ee6dbe4dd2de20e3d78492 SHA1: a847d6849c23f0e7ea1415bd95647bdd0586bf96 SHA256: ff7503494fc6d5e59b71b6a870492c807821d366b8ea8ba60b658bd47564ee7f SHA512: 3f4cd1bda0b988528af0665feadd72cff27101222b5a2e73c1fffd693ed992e72ac2d02ffe72b11670ee24a0c566f613cd60329bfe2fb823ca809115f4678161 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12700 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-dds_1.0.0~beta.1-1_amd64.deb Size: 2555620 MD5sum: 2b2dfc4697fce817763d16acd03e59f3 SHA1: 73d6a8ead89adbc4c48ea4e5e4ba73e42a06ceb8 SHA256: d5082cddcfbe333c22d2bbb49a55aed2adb4ee787317fbeac98584fa82cd15df SHA512: a196a290c8fe9d05288de0d97ab559712dec6e95a4dcc5fecdac7b8cc9b7caf01a10f5fbbe53ff77db536726e566c123b32290279462b432b795afe702ab37dd 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11486 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-dds_1.0.0~beta.1-1_arm64.deb Size: 2322896 MD5sum: 2be54d507cfa4b6ea5dd69c0c45c3639 SHA1: c7c45fe5db4170a10ada24cc2413b26c3c549b31 SHA256: 31d739bbd3c23f71029e393226e99433757912802e440042c55f5ad510f86d69 SHA512: a23ed3b3216e465ce0d60c5263cbde11d98919c623aafb1f6e37f9a51bea6d1044da5b2720620252e6c6768f5dbe38bfecd4fae6880a0fbf8fce91d24c07a05d 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9552 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-dds_1.0.0~beta.1-1_armel.deb Size: 2177412 MD5sum: ebf1523cfc7043b89dac773a21641230 SHA1: cba6bae6017954c94af40e2411ce6e0364a3f129 SHA256: b6fe2827a125169862a3f82cadeb60824d140dafd687552b3e59733817fd5edb SHA512: 515b1537e079de18638a17514da38bafabf8e527ffaee14c5bf35c6f2f2d5a984622a371ce8848ef4dfe32b4f247db35ad6e3381dddbd6fd0d9059566f8308b2 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9174 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-dds_1.0.0~beta.1-1_armhf.deb Size: 2185088 MD5sum: 4537671a0ef2d502c631bcd6c62bf2d5 SHA1: 1c32c10388ef4b196aba3abe706da2c1f7a2f268 SHA256: 642ec3e7fc032323cdb6228366587d4ee28388cb6e3b8fa68c14a330a6045c8a SHA512: 18b8e787f701a4ca93aa4f064f77538d7fcde195ae55887c996370c69c1796641ee42330ecc8faeb25619f5ff0ed1ee31bebcae70170b5a5dc84c928357dbdb2 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13313 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-mqtt_1.0.0~beta.1-1_amd64.deb Size: 2804792 MD5sum: 55d629dc1187d1eb94be264bf8186fb6 SHA1: e7ff874d145c0ec07ed4babb2439143d149a2fd6 SHA256: 6f9809857a4bf3c3f006e824a74d601f0eb8bf4d173f458815a77610a66cd3a7 SHA512: 79c22261020183041fa210bf4560df49a8b8f053903168280be7a1ca6e67460f7558576956838e8bd283aacfef07b087b920399267c89b7bfb07d74ebf2dac68 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11999 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-mqtt_1.0.0~beta.1-1_arm64.deb Size: 2495076 MD5sum: 087443f4dbdb83af7b9b67a1af375dcb SHA1: abc7103c4b6bd7f7d0858343b793bacf6e703d2c SHA256: c579d32016e01e6077f73aa39dcdbdd22b7d0f46a5043a4907ab4138f0a5863f SHA512: 01c65564e9bf18126db3e851827e7e80ba3087440e309494948f066282a96da03443738e3203030e16de6fb8b74126c706d7a85f8b02c950c15b85d9cd2a045d 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12049 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-mqtt_1.0.0~beta.1-1_armel.deb Size: 2576276 MD5sum: b46d12dc6629ac7b480f1f9d8ac855c6 SHA1: a93d78c2d6d76a4c032923f5fbd9729acb4d9b40 SHA256: 5cc0682486e50ae2b23c0945db45462322cc58c9e6c2e0bcca16518476ede775 SHA512: e1574648c0b91010fb88afbd275e764bdd508856b200b801afe938abd536b322db0f859b4cfd0722aea7922c0e4b7f6ebac24a1fbce9bfb5623578d57f94a317 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11974 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-mqtt_1.0.0~beta.1-1_armhf.deb Size: 2621608 MD5sum: d9fca4e9ebb7233bd47f507b5b02cba9 SHA1: 4bcf37f4768cfc83dccb2d42f082c9708244faad SHA256: b8b5e562f95949360fb87c38fe1e621b8d3a3e7e41e75b20c9e150aada8cf1a5 SHA512: 1cbdd43e0b16016a826849df1628bcd8c1f3c823db8fd7810430738cde9328b5d45365346665879c79b9dfdce3af0064bfb92974761c4ac740b21c3f82d9ba47 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-rest Architecture: amd64 Version: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11798 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-rest_1.0.0~beta.1-1_amd64.deb Size: 2264524 MD5sum: 251c8ab594f90da9a2a4aee8d6ebd02e SHA1: 1f8048de4de781ced1a9d8dd1de51d53e8a615c3 SHA256: e21b5ce4788cbf16196c1cbc0f870b886a8d149ec7f6d7efd8a05b9966fbb3fd SHA512: 2c6168bff2f89662b9fccf07c6e02a65de02932a7e958a8f1c4857178db255f885bfb292f0c355363ae9b365bf8dbd6aa6429899bfec08063d7aedb3acfee061 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10617 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-rest_1.0.0~beta.1-1_arm64.deb Size: 2059440 MD5sum: 7c3d755b4625ac0436312c20ae87f0f5 SHA1: 1e2ef41997844629ebf24d28e569a12fef858b2d SHA256: 5dea50f51bc2e2939bdaf061d948b9ea101afbffedabf5fdd6cd495eff0e6ade SHA512: 686974b900929284d78b224b51a2c6cf1d97de45818179146048c54d62dec176453e07f8eacd7615961b0eaa54cb7e042990c28fe1700147847b41138220bd65 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8785 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-rest_1.0.0~beta.1-1_armel.deb Size: 1936044 MD5sum: 8a2ea9d45efed2ec85cf84cf9c72abb0 SHA1: d88908416d1ca39ff53d978b142c23b5e4f58b6f SHA256: ab37a8cadddcd639efc605d19e785a026d76e2016698e4b46cb0a1f26cf794dd SHA512: cd45fb659091eec6c4535ee17aa6c0307abbc54a64e617a89c0c2baf9d1c90b7a63587bc52be255c16702b7db9f6d31998db6d18f19d1248742d5e19a59fac76 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8663 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-rest_1.0.0~beta.1-1_armhf.deb Size: 1924536 MD5sum: 116dfb4c27c82c167d2d972a8255fd3a SHA1: ae00d60d9704d45373e20d261d51626a8273601f SHA256: 522b16f40a651de2538a2a8fd1e3e8e4f916c62530687905bfaf72404972f95f SHA512: 6d595a6636f760c223b25494dc58d177418d38893822642bfb75b89b757831fec8e2edad67400e06dbae6cf67f6aecef28041180ce3e0b00b429eaaaae5b0a29 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15239 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-ros1_1.0.0~beta.1-1_amd64.deb Size: 3152872 MD5sum: 756b117d48da7c2ecd0a262a2042313c SHA1: 0153e0ba018ff5bc0fea4dcef3950dba41b6294e SHA256: e740ff93696f900d1ca1654021bdc9bf8e4579ab62e95490f8174950844fb7fd SHA512: e95b1593a615a4fb7b92417d40198483c3b173ef700801ec31a912afb730ed35ac90bd3d3be45fc11faf450e91ba94b310a1b055d1998ff15e730b6857796f6b 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13909 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-ros1_1.0.0~beta.1-1_arm64.deb Size: 2909684 MD5sum: a841105db18d70d6d53f6417b598bb5e SHA1: df0b632de318cfb77f8bfac0a8983ace656e5aa2 SHA256: 9728cbbbee76c962a8751c0b5a58975bf15f360e7185263ff83cf973555ea402 SHA512: f496d62336bbb0b83416393e2b462bd17d2e846b055ab80892333bec3a727b6a599f5326f43eda2c617eef002004d41cc49e3385cb91b2f2a8a0148df22d75f3 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12092 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-ros1_1.0.0~beta.1-1_armel.deb Size: 2802508 MD5sum: ef4f65b8c92156cbd7d787e2f3cf9e9b SHA1: 65f4e7c61a27845042670690f1f6207342278b1a SHA256: 7a1a272baac89bd79f5540ad92141ff84a87de2ce6e55e3a355fab5dab62465b SHA512: 8b47858c1fda61a749de78d13372b819bbb1a7a2039c76ec69d435ecc37e482a554a01c961e5d522f8f84bd6933c6eefe968247ff74338e7c7c40f88e6c4d5a5 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11875 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-ros1_1.0.0~beta.1-1_armhf.deb Size: 2781060 MD5sum: d3a9ff9b88d48bd0563aafe7027b4833 SHA1: ccf5ed86987a9bf2fdfdd00c12d4ea79c6038008 SHA256: 628b00074a69a2b0e7daff7806bbc5fa8bbbbfea6c12c4ddbdb41ffbac53b61c SHA512: dd34494b0c9ec88436be29db80f5c34f2f9614f9a4ecbe3f202c2428044148c7650ed684e5c3608f39c4b2c7019906f10e0c6e744d2504045d89ae2f6d5e73c9 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13252 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-ros2dds_1.0.0~beta.1-1_amd64.deb Size: 2651448 MD5sum: 76fc2e59d564193752e5390355e68cb0 SHA1: ad73b6110866335065e0ce1190fd37f2f0e66bd1 SHA256: 96893f4d2a092f58023e186e08e9dbe3f39c600dcbb4991a79237bdc8e795426 SHA512: 8cd7d93ce917232ebc124523d7f57038253c7d3248add8e16697e1ec15c00ae8ce7b655b014e9d58ec786be63688af51552c769ffe1a5b3f493960b0cfcf8972 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12023 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-ros2dds_1.0.0~beta.1-1_arm64.deb Size: 2420776 MD5sum: c6b84ef03aaba6ccd6577a1581bbfcde SHA1: 4616d0f129ac76c17dfb2be9c1ea74e897ebd776 SHA256: eac23c35fa1452067596a62fbdb7a78d6b85b585324536775d067eefb7ac8c76 SHA512: 3fe389cb01715ede64685883fdb18b27279ed39ac615bb966f3c33d108b5427a9c012e5b9236ac2f63024960f930f60b1ed7910d71c33ec77a785ab475f0a69b 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10082 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-ros2dds_1.0.0~beta.1-1_armel.deb Size: 2283764 MD5sum: 8f41d19e58acae9aa8548117efb304bd SHA1: c4af4083601f7e7bbfc590751420dec496b7d83f SHA256: e612f396327f846fa387d159a43a0e9166996e48db77a7785d5df59c5b96476c SHA512: d7cf42721bbbbee9f363ec13eea4dbc7c6bd93ca1f1d60c983ca11c0271b5d052f544a52d4af8668210e0e6b74cdf9afa654fff5d8e42f7c62a9f395e21d688a 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9708 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-ros2dds_1.0.0~beta.1-1_armhf.deb Size: 2293848 MD5sum: 63cf651788e7a9717e902d92995becb5 SHA1: 6b7d9cd673c937e0e917ba54991cedcba4244c1d SHA256: 61e4bd08d09432c674e716061a5b2677d6d99ee6443b89bf0cbbaf75aafba82c SHA512: ce68d1da7d28b5289e4884b122ea5d40699b21cd1f9effc1db1a98c36f8dd5243076b89ec470c43193bca9118eeaba38fe765d69d116768b3013c301aa5c69e8 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11753 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-storage-manager_1.0.0~beta.1-1_amd64.deb Size: 2226496 MD5sum: 1421ae8b706eaf15404a71351f72067b SHA1: 020f722de56448eb06bd75c577a4b4392c37dfff SHA256: e895437fa1f55a462711f90fef0674452bdc5c94fb4d385cb8783d496b50f15c SHA512: d7f088ef73948696dbb9bc99b775f8249d22f9c7a725584e7aef8984759d539b52091f1ea29517b9033fa82e9dc68731f5c800de788c662371c746378793e961 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10527 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-storage-manager_1.0.0~beta.1-1_arm64.deb Size: 2012616 MD5sum: 866440c6663261369fef0d6ea0165e54 SHA1: 50ae42368273e978690fdf0f1d8564f88cac21b8 SHA256: ca5ea84fd4b239fafea8bbea84723e1f000f225bb00a7925c436e33220c265f8 SHA512: 8cabb288d5e261a74329781eac214fe2e7984e77783013ddabe95c2f568c8eaf1f57184c113926b202cd273a043442b48eb32ec8639406f578c4ff2c65f0d8aa 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8743 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-storage-manager_1.0.0~beta.1-1_armel.deb Size: 1911164 MD5sum: 37622e8256c1f7fc70338f60f4512732 SHA1: fa997effb6bda53dae352799b588a5ce49995bf7 SHA256: 4b70fd3e5ab98d235cd2ae0a247324eafbd3f0aec99ccadffb10df79aceab5db SHA512: f230c4868af5d9ffb73c20b8ccb0e53765a1225cc204063d106c966019e0aab78bb1f67de681359534b6ffd7f44db98e7bec7a5b7f1229e8f0ef9392c58b16a1 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8619 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-storage-manager_1.0.0~beta.1-1_armhf.deb Size: 1900328 MD5sum: 36af5ee67e07e9c25d7cc32adb8af6a1 SHA1: 30e734e2380728adc763310acec03a3d35ec440f SHA256: 97b58a0e4f061c69f70ecf5b4b2a072e786a09fd885450a5f847e4f4cd104bb6 SHA512: b85229ed4904785d8a5629784889df6a978b7ed90e7d64cda5b8c11571dcb12b72feb818194699b2f03471b2417035bd03d7b48e4202b18200c0604e459fd232 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14344 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-webserver_1.0.0~beta.1-1_amd64.deb Size: 2734500 MD5sum: 825d4b33641b407664b174c449d8fa56 SHA1: 485ec9697564bef64933195ba499455f4f7e4468 SHA256: d0f3bd15372094da8141ff20ec446a2156f8a257aa6c8144a858c5d86b69705e SHA512: 87823d323936a3fcaab47e1f96fba5e515a1c44d27068f9be70d1dd6c32e8d7161d867acb2f112fd445f8f4fe8b415de3a976c96e2e98276d924716d0e01c8fc 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13478 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-webserver_1.0.0~beta.1-1_arm64.deb Size: 2536388 MD5sum: 43038b12fc98a85ecc88c8221cf817da SHA1: bd493926c1dadeeac2a4cc9ee1f92e9a12e89f16 SHA256: d83fafd01a6d7ba8fb81c15c620ee21f9d7e045d42f10cdf06bd44b5603293a7 SHA512: 637fa33bbadfd62bc3a67b0ae040f54d3d317368a7f99a1a3444090bdf08d0fbf6c93682696b344dfda81beba10442009a32b3e9c2ae96017348a83593394227 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11124 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-webserver_1.0.0~beta.1-1_armel.deb Size: 2325124 MD5sum: dcaa9f825dc1cfbe1ef2a48870fd3c59 SHA1: 8bd4c3e073d48952649d36ac168c27e2f2aaf97c SHA256: da708ccc8b038bdad16f69ae896c38e57fdd371beced2ff103741cf65660e0bc SHA512: 58943da3d60bd4ac35574da00d0ffecf98c979c5f3d86fdfcd5220f5ca9a5aa40e85a6c14f519cb0631bf286078bfcfeb3df713fbad3ecfe03d9e7d68fbf4764 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10973 Depends: zenohd (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh-plugin-webserver_1.0.0~beta.1-1_armhf.deb Size: 2306916 MD5sum: 3d5cce6d37e63a8b61f4e762999e0a9e SHA1: 4039983edbc661b685b73aa958ad99c5ff84e8d0 SHA256: c8680de9a42b8481d1164b42309b45d0f965300b233ec0577de0bd6ef29e3960 SHA512: c2ecb89a5630000040e807d445a9d2000ca4c668c558b74b712f27a26fd4e862ea83a5fe5da0b0df50a4aa61f2a4dd5db8504090e6cca3cbfc47397e27a638e5 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~beta.1-1), zenoh-plugin-rest (=1.0.0~beta.1-1), zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh_1.0.0~beta.1-1_amd64.deb Size: 17336 MD5sum: a9d71a1f61456d93dd750f6d56836b45 SHA1: 19b84b1dcd4a6219fa8b88475909ee1184893dc3 SHA256: 75a13fc232e9ed26bf6d678663edbd5c6aae1dfc1ab8c419665e6b6b6c10023b SHA512: 19ff9e82e6247a2a199683accab38788e5a9baa7d3ceb789e92a5775a0d1a557a83dd794c154fdada54ddef37175b74ed7d237e2d67b624e9d9d8ab3046564e1 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.1-1), zenohd (=1.0.0~beta.1-1), zenoh-plugin-rest (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh_1.0.0~beta.1-1_arm64.deb Size: 17336 MD5sum: 0380e56dee4c6e04f150213a8c863a3b SHA1: e3d0c8d25cdbb7ab09227d4cea3dee7821b1c39a SHA256: a825dd73da777d17d2dbdc1a13a51ce642ad0b843584c5bf657a06fe49aebfae SHA512: 3597ecd2cbfe9f85067e02c8d2db0a6f5ff59353b12ba9f362ea0a8b49eeb2c7be96f215d49639b9b6733915723e4bebe809d5442da330adea3348e34f75a74a Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~beta.1-1), zenoh-plugin-rest (=1.0.0~beta.1-1), zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh_1.0.0~beta.1-1_armel.deb Size: 17332 MD5sum: 333e3f6fe351430cd0388ffed368d808 SHA1: b93bb727a9d0f75707bf5c0faa5da36f0e33dea8 SHA256: 5349f1cf2b4e63b095a1b784a54370530d4c6546953836778ad855c6cd156591 SHA512: 937ad7613a6ccc271e18efdeb0ba9a73a9be88cebf00156150765b213d3fad1e15963b7df15bbd37432afb3475891c75554eaa4887f63c4b118d9a22bd60f59d Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~beta.1-1), zenoh-plugin-rest (=1.0.0~beta.1-1), zenoh-plugin-storage-manager (=1.0.0~beta.1-1) Filename: ./1.0.0-beta.1/zenoh_1.0.0~beta.1-1_armhf.deb Size: 17332 MD5sum: c5286d89c45181bd2e9fdfb567e5a76f SHA1: d14414e49e224d74d9f988025441ff475936683e SHA256: 8b3246b477e61e12b3513204d2e8ce29ee5ffe63dea871f3c6d8638a54b70be2 SHA512: 9c39a4846f8cf57cdc433ec95cbc6b4637a6d9bfc7e4624efbdb5fc7d70f7a85ce89d63a05abd723b12a00f628da553c8151633da4b5e72a39b6da1d19c350d8 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18795 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.1/zenohd_1.0.0~beta.1-1_amd64.deb Size: 4585676 MD5sum: e621cfd8024586d5b27f08b56e0da178 SHA1: c9eb7133b2f0b905c98fc8d4dfdad52e0b299aa5 SHA256: 91c44d000dccf899d5afeefb68ba35c77b64baa5d8da28a713b87d42bff7f4c1 SHA512: 4d6b1195e237fa20278d575821a55213d6fcbf617ccdfb044a593a0709fd741336a81cc41cb3e99d991ba50a7c88833656a9fab09107ada50095096251959bbb Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16719 Depends: Filename: ./1.0.0-beta.1/zenohd_1.0.0~beta.1-1_arm64.deb Size: 4101452 MD5sum: e6b3931320791b3d5a81339e024b4aef SHA1: abea16e66bc9bc259ed2d8a1e132176014864df7 SHA256: 42bc732ab7841f48c38ab5b756db92ba456352662e24883b805bd9357efd61e0 SHA512: 3c8156dbc9cac0aa33c59d5110fe8eaf54328beec9611057221b7ebd613f3278196a156c30b282ae6e8ccf85d29c6a16a15703f39928be9c825ac27b2e2529ad Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18166 Depends: Filename: ./1.0.0-beta.1/zenohd_1.0.0~beta.1-1_armel.deb Size: 4458624 MD5sum: 12947fcce0f689a87c96e504187bcf9a SHA1: 0a27abb6c82f61725df8f632d6d03d383056f4a6 SHA256: 155ae5b30881ea179e0577acfca2e096a85776b2d07f82acd26dfe80df20bffa SHA512: 2b448035a994af9ebfc984b287a7bce8f9531caf579da20af95cb42414be0ee4bbc942c127472770df71c23acdcf942de224762d501d45760f2c017bfd6bf01d Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17931 Depends: Filename: ./1.0.0-beta.1/zenohd_1.0.0~beta.1-1_armhf.deb Size: 4503008 MD5sum: 70cccda10db90fa1be5e0fd2ce838a1e SHA1: 122b3e86f0533474d216636a3eeac8ddc9d00a61 SHA256: 84a4229241e56a05f982075323eb51e71b4183eae64ff72130fa91cdef50bd04 SHA512: be8d9da880701f3bc1ae03fc23c7631751d6890cc862b6edccb2b574b300aa255ffb56405fb593f18980039713f15d80462be0588748f46f34b19997f95c65dc Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20776 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-filesystem_1.0.0~beta.2-1_amd64.deb Size: 4589680 MD5sum: 78f46bf296d669b35d455c61d065b76d SHA1: 6ae4534726cd33ea4afe55bd7749d5361ddb8bf2 SHA256: c1264d70068098aff440c16fd43ce26a74a6befb3b1fb161e699c0d7a03ce024 SHA512: 80110af0f93d18bfd04bc923aab2d6461ddde65b2f18975fb21a916adea91e1ab1d23802cd9bd745a7d9c89e40c6352b2a45daf609fe39abc35877f9058dda9c 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18894 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-filesystem_1.0.0~beta.2-1_arm64.deb Size: 4126772 MD5sum: a3ba4543e007d2a7c22bddedf80e9a16 SHA1: 4edd01beb84e40c4a7cfaf430218bff045dd32ac SHA256: d36cdc80d08897735d8139662baabc202ac4bfe2511fb029b93b01f9e465a93e SHA512: 97720e562eb06c2726e42c93c9dc043c3bd7ddd7e28be3723eeb139d8e190ad4df955a8b7a214189a857777ff893c6192d829858fd8f6b4b5dd236149c502a40 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16498 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-filesystem_1.0.0~beta.2-1_armel.deb Size: 3906744 MD5sum: efccefd579118dfad4a2518ce80837e4 SHA1: 184021fff2b5979bfb271e9d65b3925be0471cb6 SHA256: 0c7a71c3d0cb8c4cbf259e5d028d58d260b6b782f6b3aeba27501abb1e810365 SHA512: b3aecf836e67b70cb3f37523a8a0be3f57777d18c2f630714c7ee6c56c20a3aac530b93ab9dc6c65994e663dcf7d99f4ac1113ff848fcc507772b44736d55007 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14618 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-filesystem_1.0.0~beta.2-1_armhf.deb Size: 4007064 MD5sum: 7a264869de53a407f310043930f2b442 SHA1: e8935db416af2e76c2bbab5ac2e5ba76cea5bff9 SHA256: ba94acfaab8589fd43a17b371e7861b8cad06eb00f817ce6b4f8931dcc40ddb1 SHA512: b2e88b8ae82581c660a0418c5ac56f4556517afb2efdb1978931696307aba01b2aa123f63801fc239c2c60f71bbf1207b38d4c0462185a21124c32dc5102c810 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15594 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-influxdb-v1_1.0.0~beta.2-1_amd64.deb Size: 3100684 MD5sum: b5a197d94b3744473602f6d754059f27 SHA1: cf728b907557ed2d47d1bc52d7353f1246ae43ef SHA256: d65ffe4bb2192ad00cd1be4ace8a26371c1d7bee779ad74832c194516c8841d3 SHA512: 1e34f8216b0ae71641d1556f1b8b121ce601395f4015abf4d1dd248491caddfffd879a014a79bcfb1ca198f21dadaaa222772efe248d67c4fc81d00a8c1ddc6a 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13922 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-influxdb-v1_1.0.0~beta.2-1_arm64.deb Size: 2782520 MD5sum: d9ce363bf6b897f85714314824519fbc SHA1: eca787f509d1f28b5b52b01f3e453a1a188965ba SHA256: 151386a0779483122b0b83aae0299fdf2f6fe1d2a7e59570a9028608113fa445 SHA512: ca1f5282015bb2ee6e2c2f5ae302da587ca7a8d9fd03cd36ba06fa52b9474b71b347dde92657008d9a6776c9732ce86ad6f38d2f82f793060ff69fa369d7fb86 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11746 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-influxdb-v1_1.0.0~beta.2-1_armel.deb Size: 2536160 MD5sum: bdb20ba5d679234f7d872f386e6a30de SHA1: 25f01d2ae3669e9c7949929d11ad414969520093 SHA256: 5c404ea27139e2c6ac734b29ed47568ae619bd15542e2c84b05f6eedd3e19c9a SHA512: 4c20a2d2ab9e748fdf0420461452db1f066e6544bec7578f939347d1ea07ce04e00fd09f81c8bb593cafcaa0eaac232e724c563833510f70bf1ffb93c92c1d8e 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11623 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-influxdb-v1_1.0.0~beta.2-1_armhf.deb Size: 2525940 MD5sum: 06cc4f4b3dc10cadb009e3f14923d106 SHA1: c161195cfb138aebdc21ff65004baf18ad04d73d SHA256: 15576c12454889fa36dfd44a2f096bda58eb67c8542d467556e922111e9c70ca SHA512: d5b91e606b14dc0b76b33af5e226cf10c495f293b532386f33b6d60654be7eb6e2e79c9b6744eaf70f2b1534034ee0b4fb5e4a5ec4184ea15be0dc90e672649c 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17231 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-influxdb-v2_1.0.0~beta.2-1_amd64.deb Size: 3791552 MD5sum: 488ce0d0079c89034842dcc4784c4b3e SHA1: dcbd603ad30779dc69e5402a27283bac5afdd7ff SHA256: 3addb4408450cb2bc227cae46eaafbf3aeae19baaab51c66ee5a15f867a0fb97 SHA512: 115bec2f3684792e8d0d0af0d8a190856e639278b3b43eb13648d957a3eaba04aac9519e1c9fde9256419909c3a1243072aa2522d740c08a2fabdb163073c0b7 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16206 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-influxdb-v2_1.0.0~beta.2-1_arm64.deb Size: 3474984 MD5sum: ac0698f728fed1334c5611b8a988f2a8 SHA1: 566c2685a4fe50a53acbdc845698b6c19ec6ee2a SHA256: a8c6563c7cb3f5498575c11eb8ea7ed4fdb2537acbcf2e78ab44657fb24a55d5 SHA512: fb38da2fec2acd7418c86f56c653be2999839862ef52794a6f78639416d23f6c3eba575bfc56df8f0bdf525b18bacae0b4e55d2d3158a56127b5881024a35a34 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15546 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-influxdb-v2_1.0.0~beta.2-1_armel.deb Size: 3466460 MD5sum: 5c547c91caa041ad76b6c78cd768f6d6 SHA1: 6c988229d66ae5982b131d5d5d53406e627553bf SHA256: 007247cb48c474d11682e631d2ea04a3b9fe143010616e8496615b44596d999b SHA512: f517b18060983145fe4db3acb76928d39d3eb0bfcd5e59280df48cd7546ae1290f3ffcf7327dbf7fdf4815ff597ff5feff7dc2aa324662a82cf4223b3beeef92 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15444 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-influxdb-v2_1.0.0~beta.2-1_armhf.deb Size: 3512580 MD5sum: 38998276aedba2161039a3d96a594af1 SHA1: 47d620c240f067e0e7b977fd9d88758ba93b4fd7 SHA256: 23fd8610119c8a1170a3edec1c6f801f62f95240e0f653d279df1f4f1e7710b8 SHA512: 8e122d4b37a735886974ef9ef9c992603100ed6ca4be454fdff58af78c5d8ed28b889b884dee5e8c0801a2b7ed7dff85661d929ceb656e8c0c2649fc1d49a0a3 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19385 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-rocksdb_1.0.0~beta.2-1_amd64.deb Size: 4331192 MD5sum: eeeccad4d7154b08fafe49e5d120ad1c SHA1: 3194b5e2de1b2fdb912e63a9c82b809ef7d66fbe SHA256: af19920473023afc4d0b86320b51e4da2f72a23a6b0e20a09799f3ccbb8fff25 SHA512: 936ad70a45535c17a0b4a2dd534f62bf4d532061d0eb688d5eec0cf32abebba46504fb4812010877f59001969812ca27733184b538b9adf6b55abac098900bbe 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17500 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-rocksdb_1.0.0~beta.2-1_arm64.deb Size: 3887892 MD5sum: e37be2717f8fdbd371a1442bdcfd383f SHA1: 7e4f43c26eee1f8683d315fee1732d3d55a0a875 SHA256: 45f42ee778bf36dd93c3d487a712b63aff9bbbc63a7df5c04f8c57a407a8ddc5 SHA512: 7a803fce80a01bca1cf757a0b1467c8c7ebee2de59a7b62dee05acc2e180610c51ec23a6dd6a3ac84cf72486f1a5e69c3082c7a61e18f866c3b43bc04873edf5 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15302 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-rocksdb_1.0.0~beta.2-1_armel.deb Size: 3694936 MD5sum: 8839cc447f5e66b6e9870eb1094c26c7 SHA1: da16b97c8ee24ce04165ebea90c8fced7b122753 SHA256: e9dfe56cfaac8bc2c744b0cbbae1b046075c3333add700b46f0073aa28d72678 SHA512: c33177bfd92add93a89bb92754b3ffbca02674d6289beb5620d861a3f03bf5133f3dc4994369bb8a8122fde5afd719f3207f2d49ae15cbfefa41dfdf22b8f54e 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13395 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-rocksdb_1.0.0~beta.2-1_armhf.deb Size: 3796624 MD5sum: c18fb403f49e71fe5aa7505b48dbe94c SHA1: deccaa171a4cfc32d78281b81aac92a47d1d3de4 SHA256: 2a1ab934958230c77de53bb757e14a86a2194736044529c70bf3008580ff4fe4 SHA512: 43fb97da84239d3574e74933fc12e3d933e32c4374eae94781093fd9760d8ee97577341e39ddb53da2fb0bf3c12c0ab1e745b001d5dff2c34eb2c334796f5ad0 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27188 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-s3_1.0.0~beta.2-1_amd64.deb Size: 5495692 MD5sum: 32cedc9514a3d79606fafb34e886b617 SHA1: 2d96413698d915e310942dd466b4b2329153be63 SHA256: d2d6c047f2224cfa5e5edbe3981bddfdd17393eb37bac9fb95db2dd2305d7367 SHA512: ae650c4f003b827505b046179f0bae6dbec5ce4eb913b55baa86d7597e15b248e070181ba4edd9242cacb4ff5f89f57b2b1bd30fe3510f657806b2dfcfbb23e8 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26447 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-s3_1.0.0~beta.2-1_arm64.deb Size: 5212360 MD5sum: aa70c43fb39d987a2b499c61dbb86f6d SHA1: bbb81d718c4faf37a3e85f8cf789ab95e42e81b9 SHA256: 454a8a38f856ae6220871bf419809d1a93c01fec5774ec40f3aa37b21ddd5966 SHA512: 73ada0466002f85e88c0d182181c361d09700ae7afe09d5a25bcef917d0f5d36400095112a3de281b167f5f88484e205435350ae64de9b88708f3a5b5cc3a511 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25177 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-s3_1.0.0~beta.2-1_armel.deb Size: 5095616 MD5sum: b5251555cfe37f6712edffa7e4d0a00e SHA1: 2983f58fb8e99f987712abb90ef92e2640968525 SHA256: b743c4e640218272d173596607c17e7ae3d9496b266e8b7871e73a9257957408 SHA512: 693156ab5a2617483c306e76c757d5e5d766576708b85f508237584b8c120d6981cd4805d24193db97650e0841937cb14c12501865a17756e5d86f5361dce975 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24962 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-backend-s3_1.0.0~beta.2-1_armhf.deb Size: 5133488 MD5sum: 2c28fd08162f36a9e847739f1c23b3e6 SHA1: fdb00bdec191b440c4d682d6886621d11e523dc7 SHA256: 08e8115b0153d97ab9e6680f4e26d450e95771cf2050dfff3bd2fd820e11a914 SHA512: 5baff76cee2924955b46e460b0a63d37ddf0cea30ce691a051c801c5871fca123661169b89ab8deb32908bfbbc3521c06eee6747d4d0b833ba819dadb2ec8f81 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20810 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.2/zenoh-bridge-dds_1.0.0~beta.2-1_amd64.deb Size: 5287808 MD5sum: de892857fd59b18014db3853893fa90b SHA1: 54725326bc0d4503ca2bbd9d468b061a36e2529f SHA256: 3d0343a5c286d1cf22587fd0105a5dddc7be45309a7796c03a88816353b2f2f2 SHA512: 651df9104a1daaffbfb0fddfa5b4d7c2c6055c093a31b546c165c4d14c87a11a99adf65a37f861b89b9694be0d4a44db6366088bd909e55d6c12146d7c1c0242 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18954 Depends: Filename: ./1.0.0-beta.2/zenoh-bridge-dds_1.0.0~beta.2-1_arm64.deb Size: 4766404 MD5sum: c4fe826450495a376295c1dca99bcfc6 SHA1: e65fffb42957e3d7dfcc3c96710e0df1109cc0f4 SHA256: 3d61a57cd7e5671a3e2fee0f53cbe6d71cbdd6e5b5bec08b8e2cff85c19f7e4f SHA512: e5f5bbccbf0b6f22bdd5e629732ff07dfe551f523739d617260e33aa5a212c3a4251f7d22a7c08fcd35b97e8fedc5053cf67a6f18f5e772ebdd8b0affb5e4abc 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20199 Depends: Filename: ./1.0.0-beta.2/zenoh-bridge-dds_1.0.0~beta.2-1_armel.deb Size: 5057092 MD5sum: c48cba7d5874cd6fe7fa66218f910266 SHA1: 1d3784d6e69962d684ad6aab1e106078ed8ad7d6 SHA256: 49cf96fc8e9158ff6cb264c9905996daeaf7c35074cc3f18c483a27eec3bae49 SHA512: d36b5cc00a51beaddcb014247e04af4381e0004be6a2332428c83c750232fbb292aa44af4b1715295642620a1a5ebf4f0e4b4adfa5ef2020be7ada065df235ab 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19693 Depends: Filename: ./1.0.0-beta.2/zenoh-bridge-dds_1.0.0~beta.2-1_armhf.deb Size: 5105400 MD5sum: 64b3a735ac771c0a14dbba0cb95dcc0e SHA1: 87e85176a9f061d87ec82991eace19894e40eba2 SHA256: 7ab05f16c7739526d7c6a83962a0a66094a646a235fea8edded66698474ab913 SHA512: c385aa3f5e5d2079234239820834567eea3e77b52bebe6f7d400da0e757ac6b05afa0b4fbfb56eab240e30b1dee374e5126d5154e0a4394f1692aaf3e1f3d7ba 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20552 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.2/zenoh-bridge-mqtt_1.0.0~beta.2-1_amd64.deb Size: 5044772 MD5sum: 47943590d8f2480f2573f00990a4978c SHA1: a381fa15d3c469af45a6ed476ecfcae43f3b3f7a SHA256: d08232151bdc503bf6e6509ddbf1797d4340948b4baa7c3e1df3f5606569e79c SHA512: 4aa1870892fa411142636233110d4db5bf03d76e13f95721ed8f78afb5240e4a8c70f9e264b58a2c2310f30e2e9b5b63b96f3f36b64e6c5350f2d46170fa06c2 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18680 Depends: Filename: ./1.0.0-beta.2/zenoh-bridge-mqtt_1.0.0~beta.2-1_arm64.deb Size: 4541344 MD5sum: 34903c96e7e3e2c5f5195a90e31fd1bc SHA1: e4a32d5deb0f33c654ce138aa549f239b4f3452c SHA256: 84fc12b548ac70359c9820b919a3df3ee88dca476584233529fdd5fb17b6e865 SHA512: 110905e27342d04f1f335fa871b56238f7d0e4e90eb7e449d4dd9292fc7c073d1b55d59797955eccc348cb310bf53a528bfaaab785b2d585ddab77bd3835ae75 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20100 Depends: Filename: ./1.0.0-beta.2/zenoh-bridge-mqtt_1.0.0~beta.2-1_armel.deb Size: 4856580 MD5sum: 5a162a73e78df910fb56795fce595028 SHA1: f8dce95c5f86f4c95bbdc51ff54e8b67943ed784 SHA256: 8d6f436b233e87e108d7fe8ba868c9c73a2727b5fdc070fa8e7926aafb6e20fd SHA512: 2c27377ee7271af69aa3aeed0e9da57fcfa0db4aba09883e533f48fcbac043e6b5858fbcf51fb452eedbaf6536ac9d1a9306dc9f7920697aef61abd9e6ae8801 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19831 Depends: Filename: ./1.0.0-beta.2/zenoh-bridge-mqtt_1.0.0~beta.2-1_armhf.deb Size: 4886496 MD5sum: 698c7cd8d0f281bb655f8886d987982b SHA1: 7a9a6216830c1df8cf9dc375bcf26adb156ffbfa SHA256: 3e404cb1bf5ef103c4c1a97c26c0064546974a7cb57a83ebe705127e37823278 SHA512: ed6d4ed982bcaecaac764c471939121bf2b8c2866e2600401da6556fcc51e21c2ed0eb803829eacbd27d0b714915006170482f095e82ab41483ab26267eb3d1d 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21902 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.2/zenoh-bridge-ros1_1.0.0~beta.2-1_amd64.deb Size: 5365488 MD5sum: b157d0aa56519d85607848cd3271722e SHA1: 8cc9c683ce585100313f620b4fc57e4e8324b4f2 SHA256: 29dbf2e30f1aa8a039cc97321652f481caaabe33cae8c8ac26e0460a86e75229 SHA512: 9c8e7fdd55e6ddb67fec60aff6a4ed168e513bf3f15e602c7307b33466e3ca438cdf4ef9fb582b320a92c06670aa2743e4c696379d7f036c5c1d1525f937022a 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19965 Depends: Filename: ./1.0.0-beta.2/zenoh-bridge-ros1_1.0.0~beta.2-1_arm64.deb Size: 4837048 MD5sum: 22da77238ee6e9d3ed3fc1c77b8ec206 SHA1: 008c489a2e4f9177beb607072ad45ccdec766526 SHA256: 51e1a6a50f91e46ef45373aab7b005562b83a1a43c2cf9544aecd8d17c12b97d SHA512: 52eb5994258ec17d55dbb1f45c916889102bda55dc6f74faa203815fd0c43e43c5687654c589f9f00504744ef61704a15efff78d281917fc6cd12d3cb107229d 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21358 Depends: Filename: ./1.0.0-beta.2/zenoh-bridge-ros1_1.0.0~beta.2-1_armel.deb Size: 5180620 MD5sum: 91c9e716913a76a4e9e5dd6ab08344de SHA1: 02a5a64da90fc63c2b9051051bc10a2c171bbca6 SHA256: 68355e46c1990baf348f111f951e97f3b0b924d37d3fead95224f047bced0e78 SHA512: 0a854525db5bd91e58249518aed454082c736096854200451777503ba84df45b3436f67e5a3bfb7f94432528e059029c47fe8cb59afca87672b8385897530667 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21053 Depends: Filename: ./1.0.0-beta.2/zenoh-bridge-ros1_1.0.0~beta.2-1_armhf.deb Size: 5210596 MD5sum: 1d42bfae92b3c50196195657c7cf0f0a SHA1: d541c2efa52f250a537a29037c8ab7d2f6836396 SHA256: 2503a7bf248ef9d643fdf627932465458a63587c2cb3efcc1fefed57672ab4b4 SHA512: 3ee3e7a44d24fbf0ab62e93a00f308a17b7e5804b33e42428660dd88902723b36ab2cd0afaf9799ce5a48258bfc78b895d86ada94af66cd5521f8d5efd58cf43 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21376 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.2/zenoh-bridge-ros2dds_1.0.0~beta.2-1_amd64.deb Size: 5387676 MD5sum: ae64e4b5f560a744c3b6a22eb085e1ae SHA1: 8950ca1cfc64516553e6a386ef25e385457db58e SHA256: 37b35e11f94db0753d7e4b7536e8ee4946e49e44d0484ee6c908453b6112f7b7 SHA512: cd306fefee242ababbcda432c0eaa09c3c914788b9750ff421c8572eca13c275511f81395b21676cf2e2934402b82fd88ad2672eaf0d1ce0d3123eebbd5b8a42 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19511 Depends: Filename: ./1.0.0-beta.2/zenoh-bridge-ros2dds_1.0.0~beta.2-1_arm64.deb Size: 4870116 MD5sum: 7d5a1cb3318a3999425d8e782a54d5ca SHA1: 55794694d1c52dbc3d4dddb1157a3676942869b1 SHA256: 75e0821f90c298cadc72e09e80def5d858cc2a9e67cca25920fd14c1e8508f50 SHA512: 8d43a46fd401a939abd70da8a8b622d9f70b1ab69f08faa288b56428c4793ff8d53e0b40080c635716740a2ce978ddfab5a8dff7187fa9b63839785e502e87c6 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20744 Depends: Filename: ./1.0.0-beta.2/zenoh-bridge-ros2dds_1.0.0~beta.2-1_armel.deb Size: 5165076 MD5sum: 73829629c23cdf744d8e89add8d245ed SHA1: d2112ca6fd1611523cbabae7a3d18fb6cb6e2fa2 SHA256: 9dfede2c72e466a77bd6733c0368e5ed8243f223f9ee7bdfe938147df37cff89 SHA512: 31bff5fc9cb0f52faa58fce3384b9b93114d0e9aca7b0139e4ec79a92fefc51b797324e4d73c222b1817d366325f3c48ae463687767f569539d1cefd2b8a3d73 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20244 Depends: Filename: ./1.0.0-beta.2/zenoh-bridge-ros2dds_1.0.0~beta.2-1_armhf.deb Size: 5220616 MD5sum: a5a60b57d84f08fbd291fdaad426aebd SHA1: e212c4773b27c2b3d4305a5b787e0176c2be8fd9 SHA256: d94a99be11cf5a92e517cbf48c21f32adf60ee19d48bbb1d21b2d0c1a9799a22 SHA512: 3e1acd819a2800169fe18ed0b6fe00d7f1cedcc8f9263df375e8fb06f7eb03af236d3115e62890632c5cfce08c33586f22301e3f1c0ac2bf1c1f4c6d8b31efbb 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12725 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-dds_1.0.0~beta.2-1_amd64.deb Size: 2561280 MD5sum: 3ee64942b5941afb18ee1af809295eae SHA1: 5cde7391468e739a5843f63f4c5251858ac35ee3 SHA256: 58c3fc7bcd4117ac065c3a902ad0cb511ce13f38aca81ba9269f23b1a58f1f1c SHA512: 8609db890847d1f7506b3f227bf9361c9795566b59ebb75a6a1155ca5f7531afc7e49aed53720da33b1930770b43c4ad827416befb44110db16284e707e895e3 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11524 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-dds_1.0.0~beta.2-1_arm64.deb Size: 2329260 MD5sum: 51ba762a68239412b3fee80aa91cdfba SHA1: 58c4afcb9d58aa3938830134870265ed349a50ca SHA256: 340ff14441524c00bfbf3f0100fb1b3ca34a2973faa6deb167466fe483ce9ba4 SHA512: 06564c861971dc9c23d50eb50b9b1e7fa1227e79668801009800ba917633a95ba787314b0ffcd3c2aadf5b6a4a973bfd2d6e10786bc86304785eec908f554d1b 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9577 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-dds_1.0.0~beta.2-1_armel.deb Size: 2184632 MD5sum: 281a0ed2feba942d62d25513860e083a SHA1: a95ddc36dae3cfcc1b5ecfba0601883599d64792 SHA256: 862723c9d86c85be12f0aeb5fc5a4cadb8ada48a5c6eae38e01006ff30dab9ca SHA512: 7cf13bb5f0a481c3c9c820538954fc0d19334e47adab667b37b5433fb43d82766f9b819f3efba2aa191345d35ff56edeb5a9cd188b260b282a800e6dc7c1cc85 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9200 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-dds_1.0.0~beta.2-1_armhf.deb Size: 2192060 MD5sum: 380acdb3470f9365a9d40c8ba9efb481 SHA1: 4a69f6a1691f70d0e9eaa8d4a0122cb914536298 SHA256: db5ecc99a76d21a41fa03ff147b6f249547d9c8137e77110cbc9f0d7ce8e3135 SHA512: 92d3d357b2bce38e2e057ae1d8d455a5ddb7c7ae50e72f1f13aa97895908d213f56c0ec8a9d59562e743b683a7bb3bf0ffad0196ff6d790607104a9b6733b7a3 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13306 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-mqtt_1.0.0~beta.2-1_amd64.deb Size: 2804060 MD5sum: b498979c4ed2b8b714d2944afa4e355c SHA1: 8b375ae34da2e72ea21815732f46889a94ce070f SHA256: 360837f4970b13cff7003f0e9cf4e9c6b0ba477e3dd195ab0a3ccfeb89f4d45b SHA512: b23014b36c884092e1d89ed938f83d0152a08aed4c0f3ce6eb0cd0cdc36e0f691c259e08f2475a077291c752b991002711f484284f648aef1230f953bf75672b 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12008 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-mqtt_1.0.0~beta.2-1_arm64.deb Size: 2492512 MD5sum: 1ffa8fd29541935e70eabe997b2f8ef2 SHA1: b5173e0f6e14fd573a807fa7c34237154f7adf9f SHA256: 42c95a18abca5b9479836c6487a543f94a178fce2e6e226047203aa7bededd67 SHA512: d60360bb367b5025e6601f5cd10aad91f18798563f19f8ecef7324af6a48a212bf8d8e7a3c4dcd876fa524135e6d96eedbd657ab2496186a0a5391652ab0b019 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12046 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-mqtt_1.0.0~beta.2-1_armel.deb Size: 2577164 MD5sum: f313f26f4966758a9f936a382e4d15c6 SHA1: e6bcc595ffdc8a4ff916d26bede549d4a32a6769 SHA256: 360fcf767f5bea692c057185a0555485873213cf0eb7c79b653a36b34c1856e1 SHA512: 29321bb71b5f028e0b550bd94940a056dc1d70993385a13114045616868020a20256b051349cbff49c042bda91b15c35ce379f633442efc5bd7ecc5fa7635c5c 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11971 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-mqtt_1.0.0~beta.2-1_armhf.deb Size: 2621628 MD5sum: 72dafd12b66ce9a963c36d30974a2909 SHA1: bf87e933bcca8fe2b410a8e8b9bd276d8f9f0727 SHA256: 20ec59e506ca64fbeba70ed4ef1df7da90473dee762748405db78df8b0d59a57 SHA512: 8bcaff781b725c220f3fb040aae5b164d876c70ca40f903da8caaba0afd23e29ea2c7d9f192f15e5ef909dbb76d79ca271e47ac75e1ef111de91046e287bda33 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-rest Architecture: amd64 Version: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10851 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-rest_1.0.0~beta.2-1_amd64.deb Size: 2083320 MD5sum: 08f040f1e68b8c0ca05c41d5742b24bf SHA1: 1bd2f71de5de1168e053b38264638ded9539121b SHA256: 3c925d822972433cda4767df6b3fd75f0f83a9c46d41e0438a17ca80b8d5bbc1 SHA512: f953ac1abc4d797bfd39530e542ae9341540955ad1a8a1e6b390897794b23620723f504e55eed7baafc9bafa99aed37591e6765196d7fc0a762c40eb532c84a6 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9826 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-rest_1.0.0~beta.2-1_arm64.deb Size: 1910776 MD5sum: 60148035bb0ea4dee2e9a5e7aacaf392 SHA1: 04a51d923c65f2ea9d325858422e8f2cea8199c4 SHA256: 1bff8b6837764f5d2cec6c1cf0193d07f5fb9739d7316b92bf2f51346ef070c5 SHA512: 26e5df0e9f86ceb034f7452a5cc21a47107272ff5427ca64ca2beb6059dd2be0b8ff1710c9226141c4dc7015b77eff6fa18961f0bbc4e0364ff70cda365b9fba 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7980 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-rest_1.0.0~beta.2-1_armel.deb Size: 1782604 MD5sum: a70fd84217cb551c6cd493de007187d0 SHA1: c3a4f8b6a131c88d2a33ac2aa13b7a436a0affba SHA256: 9cb11c9686f67889d916507dd28f11e0b12dce75da51d810f06917f52422d9e0 SHA512: ce9d3a247485ec77fcd0f2157a2b4a59454a45a280d8ccd5b084028836f97e84a89e8b74467039d0889f0cfabb3a4b3d790499ce12edfc6cd52b2ece2f533aaf 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7887 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-rest_1.0.0~beta.2-1_armhf.deb Size: 1774000 MD5sum: c344bcb218145df475e56ca834ea8c63 SHA1: 44ac0bee365f3fd68741e5bd2cc7d40ba7268a3b SHA256: 4aa3145fbb5271d99366c294681fb98707ff662422b884fab0926ff1ae4d5d27 SHA512: e4eca0130b2d2672cd22ecb1bb44ebdf40693fbb3e071b257140628658cac36a62d79f198c66973657a0103fde66a0ff12a873205abf54866e5541b8b3984d6a 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15254 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-ros1_1.0.0~beta.2-1_amd64.deb Size: 3158400 MD5sum: 09488241e290150541f084888539c5b3 SHA1: ca20924f03ec64ffb49f54bfb55160f4bf4f6a37 SHA256: 3185ba197ec248430a8c94ba054cc903b9e72768e198e49ece128a7363c12949 SHA512: 6ffc8ceb8b405c79c9a88c4095ccc7a23d16c112fc93965caaa4d74dd3c87fc9168a52cef8ed6a2d7296d6a835bcff3bc7228cca54ef6ad394b700448cbd37b0 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13932 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-ros1_1.0.0~beta.2-1_arm64.deb Size: 2911940 MD5sum: 801fc3cb920cac5f9119df85cc8644c5 SHA1: e6b1e30cf74b20a3e886d54f4058ad75cf5318f2 SHA256: 25f1e048d276718106208b201bee13a31d5941bd001c4275fd0d7601d668041b SHA512: 640c57fc568e159ed92e851d570c6a192621efcc22f32719d31b0d678c4a8416d455f1b530c2095173b6cab3c0353ce4005336a9794ca9dfc97a1e2ac9400ff6 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12112 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-ros1_1.0.0~beta.2-1_armel.deb Size: 2812860 MD5sum: a3bff68ce8c1e223f69af4b396fa9061 SHA1: 24b1f232468360716b8719653f337d670f637948 SHA256: 27d8ed71199951e0d94bd87ddddb3274634c165d5be59411b79d5ace4866391e SHA512: 4f7d17e8af8cff589d435468010ca373026719d9102cedcd398d7f9cac8614f8817a768ac68e2e6fd34d9c07fe310dbe76ce075f881016dcd5a0243718b36531 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11895 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-ros1_1.0.0~beta.2-1_armhf.deb Size: 2785904 MD5sum: 7d7dd8d8ea1ad07cb182abf3f473ba7f SHA1: 78bf85d4a00582f83b18a0eacdb589d23df7591d SHA256: e9e0c524f487f6be7aa5ea18f8764711ae801f8ef344b99646a097ee9d9ff8c6 SHA512: 31692016462df1967dc31202cecd35cdf5cd6bfaf4118229c282d20ae8229824730311322fabe33bc1c39506234843fdb6a1532fcf281dc144cb031aef0449fb 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13280 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-ros2dds_1.0.0~beta.2-1_amd64.deb Size: 2656744 MD5sum: 0a8867a09c430c9aef67af3a05e4c847 SHA1: e820eaa0713b11111e3086dd0d99d35515c71211 SHA256: bc56152dd0cf8debd55a5bef645d81f983cbb60ffb7fc9bf35b57eef1aabea06 SHA512: 32cc4c4ecfe621fb2be4688042c5cef51447895ea95b45321c04176ffc65ad26f20b6727ee07f2e5d2f23af0d58e2000ca8b8d5bd7cefdf81c8aa1fc50638289 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12031 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-ros2dds_1.0.0~beta.2-1_arm64.deb Size: 2423788 MD5sum: 984374cfa2376d6768f6a48ddd1d0151 SHA1: 04946d319f1643e836e9d7eee6945172b6ac44fe SHA256: ceedcae61288b2f7b5223941cbaa1fb83bc279a0df5627bea53c2106802152b4 SHA512: 66d873c3a34642349856dfa92b223388b6f147541cbfb987e6bee32fc8805e2b865c70ac6798479abc991ff2455332c39928b6b3f4bf2ccc1f3c620f1f5425b3 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10107 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-ros2dds_1.0.0~beta.2-1_armel.deb Size: 2289856 MD5sum: d5afa7cd73ea8fea8b934d0b2b0f39d0 SHA1: cb736758d95fb84e1f61d55ad6d56e2246c88676 SHA256: d04395cd0daa9f5b3469e9074bddf11f69d843d019c15e9d2697609ae31fafe2 SHA512: 0737e646d5d0b8e641cd5de2cc2a5c1f570de06daa39e713b545f82ef9080a2178fc1b4a78e6c6f066c608cf1d2be3625961426356697c8d98bb52e5a4d8f7f5 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9729 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-ros2dds_1.0.0~beta.2-1_armhf.deb Size: 2299584 MD5sum: 0a7ffc62bc84742b5b0d409408f49cce SHA1: 596b60c35a1582b7044727dd1382ee5348270d72 SHA256: 141d21af14f7346203ae2155b25a71982b6c4fc176c4a8b6cd4f062da6c14925 SHA512: 604bd50e6d0f95d9000f1eb9b20edb9090e06c7446f854b1f6b34a9c0f964915919d4e2ed51d03211823032762e7ecad8746a70e67b383792c338a609b57e4c6 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10836 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-storage-manager_1.0.0~beta.2-1_amd64.deb Size: 2050928 MD5sum: 3c33967e320f35de40c5b5610be67941 SHA1: 551051c504aab70edd5d10b42e2051a3fc0bd223 SHA256: c7702714f6c448c7d413a2e97c3b881066f2cb6599dec91004bcc1701e133b21 SHA512: e9e9a88634eb14f07b65764de225aac326b4c904d421b6412c35cb667b5b4ec9269e4f240b6b86d68b6c93c6d9d66bb31ce77ae765837ecfeb74ef1a87210399 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9769 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-storage-manager_1.0.0~beta.2-1_arm64.deb Size: 1869488 MD5sum: f2fb8abf9a4a4a995a8063668c3e0f3f SHA1: 2004d83441cd7abb48fc88449ef28e35d76d8f3c SHA256: c45c2ea917a5d68da6930ee8f82ec3d6f1fbe0ed6f2325b496b26303a4af072d SHA512: 2bde1a7cbfaf77d8a46bd9cc8ea94b2638efac16d0a3a2cd9179be5e93f12f43be62b456cbbe702ef717d6a5720230b967c4c3fb5bd624a3f009148e6ba4211a 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7973 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-storage-manager_1.0.0~beta.2-1_armel.deb Size: 1765780 MD5sum: f4fcf815137b341aed8897c9260f0f69 SHA1: d8a015fe58f6101bc9a32b2eceb7218a90bce038 SHA256: 75334f9c26be70f0f312835ce1bc412227818861c27a319ff80923e37f75b64d SHA512: 9191fd57160e9ebd5a61f0def233c5922e5c8866222cfb725b02b9bb2db00c3b0f48a763f8626ab1f51859c20048c239d6df21d1cfa59df52553ec03094989b3 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7874 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-storage-manager_1.0.0~beta.2-1_armhf.deb Size: 1756860 MD5sum: b79b3a39a1b3822039d01c359f49756f SHA1: db96617a85a035bd9de7005c67fb0be8d243992e SHA256: f42d88ab3b8c12a2aa060cf67f937bac56d13cc45de069caf92f9994a3a4baf4 SHA512: d4d268efc734644523d23921e8c2a9f01cb331ebaab5e461cc490e88813ce63cee5bdd07dbdb74e6bf6a925bfa3c35601d5697616ecd5074c8209cbc11a0f4a3 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13326 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-webserver_1.0.0~beta.2-1_amd64.deb Size: 2526744 MD5sum: ca863d854678f361e97a64ce55368e0c SHA1: a5a9b7fe7a1df51fe415d3fea78e12ba73b464bb SHA256: 22849acea4305fa8c2a5930f52071bce8c3db3725c33ee007d4fc9aea87576d2 SHA512: a64498f6ca8f482c1fc4ed6b3b2f149d07b02eb0b5fc50aa7feaeb3135601cee14b070217dd616e833ebdaa47c1e366398be5d8fb1991067662ae47bee33ad29 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12519 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-webserver_1.0.0~beta.2-1_arm64.deb Size: 2351800 MD5sum: 3f8afe4c69a997096d214612d2c4f4c0 SHA1: 0d03ad495e5edd00f639df4119fb7222539d8819 SHA256: 2e180e5796f24c5f24d401333da83f8651052c14cc6db2c0928cd257160f6a42 SHA512: a150822281a70f6439083a5496cacb6057627c0242c469194f02548f91eaca728d056a888bebad1c9d493a521eb9660406a95ae782418f9f78879cea9f8123b0 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10238 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-webserver_1.0.0~beta.2-1_armel.deb Size: 2154176 MD5sum: 0be7205e8a92a080964dfa161758d4f6 SHA1: 2c7fa974ce473da51a745615ca940c980d91d2f9 SHA256: 7f0972e5e224d776a71819a445a9b054abe2f8664617b8db11a22efd68d50b05 SHA512: abb2994ca955292d5425ec9efbb2d8991990bf413effa21d353fbd01e8952974a22a0ee9e96c50e0ad0698ef63ff1e3117e7cc3963d65f17cf611cc3ac2b64c1 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10111 Depends: zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh-plugin-webserver_1.0.0~beta.2-1_armhf.deb Size: 2139612 MD5sum: d1c8c6f81a82068615cab7577dc13c58 SHA1: c7fb46c60de8e36ea8c8f0a387c236cf43b79ab8 SHA256: 391ead9497e7bd7cb992110ee940960fe001e349254bcd4d2def76046727ec47 SHA512: bcdeb936a455a46f6b85870441fd1b7a7e165abf06e43c41ddcc1d842fb09acc1c9444aff378ad9ca972d67279a2e2f94a5d8a76bd7e6ac0512d4211d173d71f 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~beta.2-1), zenoh-plugin-rest (=1.0.0~beta.2-1), zenoh-plugin-storage-manager (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh_1.0.0~beta.2-1_amd64.deb Size: 17344 MD5sum: 9cddbfa4befc0fbbd670c2f4682d671c SHA1: 5e22c574c2e8ea36c72062efb09e21634e23e606 SHA256: 0292b2cdf01df931566f00430a90f88f94e83e5c971a18603aca1953f88be74c SHA512: 2cd6127aa46205bdbac21d47f7c203ac7a1dc23bc47f6b94a7cc93f471d3b672cb66d70bcdd5829d364da275f117de13f88ea4fce9143c35d07d61717665f481 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.2-1), zenohd (=1.0.0~beta.2-1), zenoh-plugin-rest (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh_1.0.0~beta.2-1_arm64.deb Size: 17348 MD5sum: 38a0184223b5c6315366bc30bd3f81b5 SHA1: 22326d6e54e7db89e7a04ddb93e887b2a75994d0 SHA256: fac27ee32d11899e43b8dd6b93ad8152252e2dcec34df907ef8e9cec7403298f SHA512: 65c0b6b5d86bb614203bcfa5ad7440ae39cd36b464787f2ee9be63a28530241ea2bb1acc7b068d6c0af14c3ad2ddfc5549eb727235dd7cb8dcf830d972cabab3 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~beta.2-1), zenoh-plugin-storage-manager (=1.0.0~beta.2-1), zenoh-plugin-rest (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh_1.0.0~beta.2-1_armel.deb Size: 17344 MD5sum: c6a608bb3376e7e6f92ae7d105d8c546 SHA1: 6b979bab1bf4f8635b7ed719ff6b5337adeac5cb SHA256: c50f7e16bea19f6b868c1b22a847f8248cfb384b270c9b17fdfbef5bbb91bb7f SHA512: 56d11dfb523e378abcb3b532ffffe7cbb13daf71a78bb2680af7cdef1e0c71c4c64cc62813234057e7702f533366333cffe458c5687aaa773b1d57fed2e8f810 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.0~beta.2-1), zenoh-plugin-storage-manager (=1.0.0~beta.2-1), zenohd (=1.0.0~beta.2-1) Filename: ./1.0.0-beta.2/zenoh_1.0.0~beta.2-1_armhf.deb Size: 17344 MD5sum: e961d5d513ced3dbc229f2c9c47f91a0 SHA1: 5759ba1891cbf0ce858fa02a00b1f1ce4dd08d14 SHA256: 01c371d8083f69b032263749f58f3a76e2ec096ff9f58b4f97cae631fab51eee SHA512: 59f7fe618132f80c43bb81e018524a18863a299ae36c5ae717bc3a7885356cb3425ebf70f88a2d1f1d4c35fe1b9f29290a0ed52d01c60e9a0e19febdd75355ba Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18147 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.2/zenohd_1.0.0~beta.2-1_amd64.deb Size: 4414488 MD5sum: a0f2f60eb47a09168cb124b36c679c8f SHA1: 0d89e9f9689c70dff916e7ef59b9a110334d8c41 SHA256: ab55a5c3d6e2ae6397deb3f1d613807c6c373bf75a50896b906ff507e756386b SHA512: c1b6be0efd65d1f32228d5b5dcbebdcf549aa8540a431a272ec53df858bd70b240e6d4345ae8f015b69c663bf478af07d71b2f61583b252d5ad62e238922465f Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16239 Depends: Filename: ./1.0.0-beta.2/zenohd_1.0.0~beta.2-1_arm64.deb Size: 3956744 MD5sum: 78dede3db9889629bab55a9ab64389b3 SHA1: 242b568bf1a9f35c14037fb3616d92af91719160 SHA256: 30a613e4a1abc64298833abad2f21abd8232ad693b427902217bcffa635c5863 SHA512: af8f30195d32de339d55bdeff0ea95bd469e3392da62801b4f91b2db273622bcdcee6d6e1b3790e40b8bd789febe3e511c2a4ec4f78a747013e50bd199f6f093 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17637 Depends: Filename: ./1.0.0-beta.2/zenohd_1.0.0~beta.2-1_armel.deb Size: 4317304 MD5sum: c05f1c747c8035b659cde1a0f798751f SHA1: d916cb445baa87720f8b3c416113c17bebcf6e07 SHA256: 25bf77a7157cb956d8a0f2987174b08a34fc6879e4d4f75ac0a23b85f504a639 SHA512: d6687442f90c5031b96f414baab82fef36ceab64c9eb36a2cbaf012aad598ea3a634041d73cd156ce754ca2e77f3a060d30e0007b08adf399801ae3d8bd6a7ac Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17435 Depends: Filename: ./1.0.0-beta.2/zenohd_1.0.0~beta.2-1_armhf.deb Size: 4373172 MD5sum: f342b69f32eccd2af04fc1e1a91a27a4 SHA1: 39f8ea2ec1b91271b31882328047bccc961d52f6 SHA256: eff6dfa7477bc2f1d93e082507155486a3d99837efd7790378bb38cdbe1d84ed SHA512: 456d9fa0b4f7a08921c01eb82e0a21097f6a3b176b6213d1b4eb871f21035868cfc3cce849c5d03b1b050caf96ccf6fa635933908696cb0c80314042d422e734 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20841 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-filesystem_1.0.0~beta.3-1_amd64.deb Size: 4602784 MD5sum: 37a60bb0c3172e06b2880fe250dcf72e SHA1: eea0d5f0b8311559b4aa0e1af3dbae30851a4e23 SHA256: 2e14fb7b017d7344293ab32ca20d02fb9d69875bf4630494c413a791c8a55c80 SHA512: 181b9a1c5d4d1f18727b11d6d3e3bbbbc694804b210939892f1c8d4210fef0093d6e7ff0b3b52060f9e7dd79f7fa0cee5f37a2b421136d5adab6913d5b4ed0fb 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18951 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-filesystem_1.0.0~beta.3-1_arm64.deb Size: 4140192 MD5sum: 2f41e8f0acd1fbe7935e86b57a6eb214 SHA1: 98523f82bfaf01e3eb5e3f218d71151ac2588e37 SHA256: 61e79a58a0860758fc4b5cbc9ef3a71148e4e193d75819768d9190e984b25f5a SHA512: 2b8f438a8dba670229fe6d0169ab68a9c2796f738542abfe1101bf35a01e1c7c5ad1fd9b80543b30f2bd4a2f76182d915beb7326a260ff4f96740d1155442426 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16517 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-filesystem_1.0.0~beta.3-1_armel.deb Size: 3910120 MD5sum: 66ea4d4d5dcc1ac1d58d8355f7b918ab SHA1: d0dcfe1615fe95469e1525e7137e2e9aeb89d975 SHA256: 5e36b0e4f7a628904c142b2127efb3af0fde2c904ac86bcd954403e2f17bc5e0 SHA512: fb9288956ae69360c6dd88e2bf92db1d07e6c959641b4f51887b50e911748799dc3db407268947371b057dfa626eb7746455815e2a889051463a09dcad47411b 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14632 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-filesystem_1.0.0~beta.3-1_armhf.deb Size: 4007916 MD5sum: 4733cd09e102b2242a029764e88b88b8 SHA1: e366594908f0515e9e21144b99bbd02fb44c83dd SHA256: b8d1516111b4b9fc92617f6f0a6c0a5b88863605cd78a183bdad8bbee95f26af SHA512: 38eb71468618b09f9b01571b916f891ca48130229892c4586325a6e085f2c898e57bc2393f2d16541d839d50dd83428aafb6e7e259ff3486a24d93ba494f8c67 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15712 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-influxdb-v1_1.0.0~beta.3-1_amd64.deb Size: 3129596 MD5sum: 4646bf6da692c9ead1f69254c374152a SHA1: f325f9ffe86614609f0ed12fbb054df9e4785458 SHA256: a94ed20502ab1c1c8bd57e527b264e64f09627e34c2f301f370b3f0cf5919312 SHA512: d1a7ba12a381e43c771391c288ef6c6a15e4df27fa4f3a062f7b59e3f37ae3a9467fb72bbacd2b5a7ea1d925073dd24f067b8307e0ab2d61f5e3aba4167e896f 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14035 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-influxdb-v1_1.0.0~beta.3-1_arm64.deb Size: 2815928 MD5sum: ea627f0aad53621c9ea61411f35f7df3 SHA1: be38849851550e3d0c2b036aff240a1df19e2ae2 SHA256: ce6483ccdcf6c6d0bb56659224d6c4e907a5fe5c7b515cbd1844251fb189ee41 SHA512: c27ae06dc1c350f913784dc6249ef58d921e94451463070dfa257e77d1e4505b6ab46005457718573e30b63a95efc021ef9e1f0a9452a986ab78a7074d082f3c 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11805 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-influxdb-v1_1.0.0~beta.3-1_armel.deb Size: 2553748 MD5sum: 1ccffbc2c87740b4d4377b7d31e403c6 SHA1: ec3c6c1acaa6d968836b5fc754237fb53aa2ca43 SHA256: 35061d4915fc85b622f40e371b175c2cb38c7689ecd5bfdd452eda1e35985086 SHA512: 8d048d9a447aa505cc94dd6ecd7d605ccd096ddf6a1c81228d2784535f29c4a76f0cb92f4e8b43358d5a9b79e34374c7057827ee735e6abbc4a3709512f18530 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11682 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-influxdb-v1_1.0.0~beta.3-1_armhf.deb Size: 2544060 MD5sum: f0138f43614018da74ea632dac1dacc9 SHA1: ecc413c4df254d59ee1a640f200390455160ebaa SHA256: b93254771bf0ce1ca2e578a4a557ad4630110ad1fe85df629485b3c0260da9e1 SHA512: de008754e57044d794cdeab5981b05362de632c8ac29ad8f68ab49e5f80c3e6c0e822f52d780d2df5769075045623231c4aa35258c4d3299bdb80e91a50dc7fb 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17301 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-influxdb-v2_1.0.0~beta.3-1_amd64.deb Size: 3803840 MD5sum: d968ab594e588170a79a4fda7186e2dd SHA1: fc7941fa49b4ab6876fb26684e8f90303a1775c1 SHA256: 3147a5737d2d4de321b33a9c789132fe27ab3a1171f414c47d312c8b27c944fe SHA512: d1823ef5597b7786e02ecf963e2ed5f5eb12b1980f7af6cd545d2675e31b1aae2ec887e769d10befa89746a34bf6558b0bbe50ae6119d7ee441ea81c0d43e85d 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16280 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-influxdb-v2_1.0.0~beta.3-1_arm64.deb Size: 3486040 MD5sum: d60623c83418ae9da6b4ce848d8e1595 SHA1: fef34c23f88d375ce796bda8b58c1e7b77b27897 SHA256: ccac3975e198d13383706ee2af1d937858436c5631a6ee921b97add23a964843 SHA512: 8ec5878f2c224b8f55a9975b6b2d00aa0e17f03a622d08649034d4406bfd456bd1a83c3375156aa467976231aa1cbe054f0d29601b96347c48f6d6b1a97d7c0c 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15592 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-influxdb-v2_1.0.0~beta.3-1_armel.deb Size: 3469556 MD5sum: 1511ad9f3fc5beafacc8d5c6620e8fb3 SHA1: f4d1e024896ef2fa1784ceceeceaba394e8537fc SHA256: dcc363d8c8211eeb91e1fbaef1d289cf3cc9915d0dcf3f7bb76181d6ba98d974 SHA512: a1272feee915d7cee41f386d2a65e662e870954cfa5c194557389f17b45365383bfc5d40a04d16363ecbffe67aa5defd55ced589921fc3d5421bd642c0747c09 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15491 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-influxdb-v2_1.0.0~beta.3-1_armhf.deb Size: 3511956 MD5sum: 8e0de750f3d644617e6e24bb01a5bbe8 SHA1: 1f7f16b34887264a7d8156c8c73211b5aef869cb SHA256: f1d8e7e62b2a98d18520c2b1de44ed0a9a81391fd963fc6fd5c7226ae06e4842 SHA512: 21c53dda03cff820c6dc66030de4610bf6740477fec7b962c9db524edf41f9f1e4e7650542e4b5e07e71c454f67ac3bfd761408fb8c250dd71018b9172600caf 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19399 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-rocksdb_1.0.0~beta.3-1_amd64.deb Size: 4332116 MD5sum: 4cabaf15e6d1aac941c44a7de43b2d5f SHA1: ab5728d6f0d7624d28087725ac222d3eaea4af3b SHA256: 9d6623720cb25c1851d8345c143457a6ef2c25f4dd085e566615a367e38591cf SHA512: 5880e20539617d74f4c7e42da038253cbd1c92434abb84eaf4cfbe068b88540a4abd77756e96d6bf24e27589510002038c5c014d8cbbc3e9d1e6b1fd801178ae 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17514 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-rocksdb_1.0.0~beta.3-1_arm64.deb Size: 3891984 MD5sum: 5a81cce094d9ea5244c69ca6f9b76f91 SHA1: 8b6e25038c5eeeffe0c6c7f4e4275262a178803a SHA256: 85bd3353d0213aefed7f10918f0fe7c8830a19ec5b4eddd523ad6bb50fa4fac8 SHA512: b778291d3aff6debcd974fc76dd62e9b20e06d3b188a8cd4d1574b12f1aa172819a0dbc20aa3f713b649ce4eba9318dddab96870f2ddc2cd7c6aa3471f4f1cb9 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15314 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-rocksdb_1.0.0~beta.3-1_armel.deb Size: 3701412 MD5sum: 5795f597bb85ed119f618c1d678ebf07 SHA1: b1a39be3e04ad79c0183a8907135f79795851a0a SHA256: 0f0306c422591003d4219143be93cc2f38f9c531b206413de7796ae28bae7a13 SHA512: 61aa2dca038b47fe8ee59bc9c25c422ee0e0c6361823f19fe5424e788d535a0409b73ffc91247784349a21b3deeca1b6001b5ffae1ac24d9d1fbadf22f3b0991 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13411 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-rocksdb_1.0.0~beta.3-1_armhf.deb Size: 3798216 MD5sum: cb693362f82c83cfecab049d7ef27b97 SHA1: 81ad1d7ece7be8f54cbfcd166e7fb61c72f6b097 SHA256: 0495ba0566e7d6efe8196c4b1c642a9877e599817bd8774532d61fe698f8d1c8 SHA512: 9d962f9b0c2959927df0bc3bc6da62e5ce359f939a9ddda8df85e645d648e4d3aa33d9fb33eef1d896bde3911acf08cc0393d76d3d5c1a6673ce63549c2fdaf2 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27270 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-s3_1.0.0~beta.3-1_amd64.deb Size: 5506636 MD5sum: 4cf576bc149d965bba865db7c17ea136 SHA1: 62eebaa9a1952d4f75dbf31f9ca5e31972863290 SHA256: 0dc15bab34bf7000bf8c0da31cc1dd22b6918c99071fa4b6526907c78c99f657 SHA512: 0eb29541fe2a01a8c36d861bc6f2e9362b05fe9a3b776a8e659fec09d6619e229f2f56840f0fe5d9db004cfbed7c04ae21b24a834a95b796276719759cd647c3 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26494 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-s3_1.0.0~beta.3-1_arm64.deb Size: 5217260 MD5sum: 476016bbc3737af8d646f6d23dbc6e1a SHA1: 7bfafd1885c63392a60e57281bce54deabca7f8f SHA256: 37f115dad15962b3c083e4b30a1e6379c25049ede13766da97ae323f46d86dbb SHA512: 1ad85eaf20589595a6ddc11d0ce9615578cfe957d7ecdfad95b4cdc0b920ac81be812b079ccc0a6ef024d45daeff0f71c2640cf6f5d3d7ff65c28839d643b5dd 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25211 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-s3_1.0.0~beta.3-1_armel.deb Size: 5095048 MD5sum: d07bc2816d488e9d3734554892025bdf SHA1: e2bb60261246989ef00a7243b7514d78728a1717 SHA256: 9a25b3ff6257d5ba7dd2142090570e06413a58fc63e0fa53b0dbb80bd438f0e4 SHA512: 9e045007227032cd98187bb00e85112b31410a643d7a23928fdf3d60ad04533701ba0a2a0c39d7d542aef3251e9b072ad3ee8fdd93639b5829f0d6703bb5c523 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24948 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-backend-s3_1.0.0~beta.3-1_armhf.deb Size: 5142116 MD5sum: 215f37456d8b0aef24e41fd6e9d34003 SHA1: dbab34bdb5fe99a43eb6a391d71f2e9eecb0e64a SHA256: 65b9d702122121b38757de748de42d6c06af4c1a104e20ec50cfd4ef796c92a3 SHA512: d4ef93bbbab5e6085d1cdd713aaf4b57d24a7babf5ca7da4e1ea24e70a7bc730f34758d6433e06605c802fb89d511276542d108e2623167308ccfb8815e0a435 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20489 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.3/zenoh-bridge-dds_1.0.0~beta.3-1_amd64.deb Size: 5249048 MD5sum: 42a1b12bff3a1754ea938900e2837747 SHA1: 9dda2af34acf1f92bf0f15fdbd65051fe449aa76 SHA256: 40fae3d1ba79d27dda994ae22de23e6742ed9dd8cf767265ee8e2f8ce9155cd5 SHA512: 4bd54be266d81829acbe21e9016ee155b5aa201e6eccc94395035e5dec647d8ac05e299135b695c171a96b76ea5fe1a944a575dac967e617d4fbb1321da5e393 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18726 Depends: Filename: ./1.0.0-beta.3/zenoh-bridge-dds_1.0.0~beta.3-1_arm64.deb Size: 4746172 MD5sum: d3bd512f8311bad6b8640d9264087fc8 SHA1: c5b00b305fe51ae04e2f98d2b2e28d8acfae2ded SHA256: 02932e72698273a6aa8ad48d13ffb0d5b76c5faab1807b78cb9d5627efad04ca SHA512: ecacd8787ba9408543ffbef1ef5c8125225db24acb27e23ce99fd811fb602efae25e2f9fa51c23e4136a8f22c1505877e5b805b38b850efdc691f1edb8566d2f 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19853 Depends: Filename: ./1.0.0-beta.3/zenoh-bridge-dds_1.0.0~beta.3-1_armel.deb Size: 5008456 MD5sum: 738dcbc7ff578d7307678dd5138b07a8 SHA1: 423632059b1f7ec5c3f7b1434a49e319e497091b SHA256: e5023ec16b9817d4591bf4706ec56558e04fa3d875a8af7612fd44ac47276095 SHA512: 14af6a56344c96cd54e8a3c73f7bafc3810df0443b37233993e92d839b4211d58c4a8f82905a8c6c8d46ba9b279db690cbace5e15c5922b1c83736d3fa8e5b7c 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19344 Depends: Filename: ./1.0.0-beta.3/zenoh-bridge-dds_1.0.0~beta.3-1_armhf.deb Size: 5061340 MD5sum: 86ce137eb99607e1e46324c100723577 SHA1: 123d45fca67be059ac4c58d0f66cf313ba9067c4 SHA256: 56cffbd650dd9e4098858b98bd6d826327b0730d7ff695c08bd6bf7bd0337c25 SHA512: c9487c77641116e96b8aba6598802babe837f9fb18c0da20177b122ba1543e056c649eeb158ae43227ffe27b72ae9f695a34337bf5d20588ab85df4e3ca08e67 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-ros2dds Architecture: amd64 Version: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21060 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.3/zenoh-bridge-ros2dds_1.0.0~beta.3-1_amd64.deb Size: 5355016 MD5sum: e9c866806bba9fc22deb14208737e1dc SHA1: 244bfc06463dac64772b8b10fde8e33acf6cc7a7 SHA256: 0395c9bab580ecbac539d1b39aa71545ebbde941a97604dc8b48b9f9fb336512 SHA512: 296bcb9927edcf5f4a331155234f58d354336894b91a8f17646a3866ca8a1244c0392cccd1e7ca14ff68a3e810929a3089e3e44325b2f3d3a88292b1900e11f5 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19252 Depends: Filename: ./1.0.0-beta.3/zenoh-bridge-ros2dds_1.0.0~beta.3-1_arm64.deb Size: 4855104 MD5sum: 1ce7d1f7bfafa69d1b6dc0741313bc5d SHA1: 8d536bb226ab8ed70a12bdd611691ab9ad21db44 SHA256: 391e8eb358dd8ff1dc20e4e50a9d375c2ca18768982095293706c15d00d090af SHA512: 7259ef2c1266d94bf44d8554be512dfdad590bc16c6358e3090ee2254c42c50439b02925a886880d6caecff660c7a4217620a1bd70cf10b10a866ba401da0e74 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20398 Depends: Filename: ./1.0.0-beta.3/zenoh-bridge-ros2dds_1.0.0~beta.3-1_armel.deb Size: 5122824 MD5sum: 6f6f96839a265b9f12c4c2876c8284ef SHA1: 0318c01a2fd9fb05081131042b56950648c29348 SHA256: 51b66a804f1818b4dba09edabc27722a34663416aa7ba520bd8f03821bfbcad4 SHA512: fd31637e7137a3bfa42683a134bccb667850155c1e4ca45d2a58acadb237b4fd9c1c415ca5cc471c2b852173001cc2a096c0a16f79b2a6b7520178ce414af92d 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19893 Depends: Filename: ./1.0.0-beta.3/zenoh-bridge-ros2dds_1.0.0~beta.3-1_armhf.deb Size: 5175308 MD5sum: 31ed7b78e086619434526160d555ef75 SHA1: b1071690195df15c59e5c23f8fadf62b75467154 SHA256: 2ccb3a740c3903d77ad60aeb51bc413bf9a7cef248084b12337bfcb53f1509c6 SHA512: 517438841b4193658c5b9048a9ace42197d00255d82ddec1fb24950c8fd80d78fd4358d1c03ddd6ecd9d5d5cc483e86c42f91bb3fe57a8af4bc3d6de140aa40d 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12764 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-dds_1.0.0~beta.3-1_amd64.deb Size: 2571832 MD5sum: fe73992cad2d2cb8ee8a77a213a3e902 SHA1: 75aa5898206fae42ea2f20cda384b7119fc291e8 SHA256: ab6bf198f66693d4e597f21a7888a83b55682767758f8b815e1245c45ed4f085 SHA512: afaf1dcb9a65fbee5d18a04cf7ddae72d1e995f812d532f39f0e3357a75f1384fdc2ef3cb52df16256f7fea235d021410271a0a41732d3360a8a2000371d8339 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11554 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-dds_1.0.0~beta.3-1_arm64.deb Size: 2340132 MD5sum: d6c35ffd6814e2fa2be71bb4a91ea004 SHA1: cc6aa418de2f4ffe35c6e31161773ea54849e15d SHA256: 9bf3bd27d272495f8169cd8684ccabbfe29622f65019091e88d95a7a3ef2dfe3 SHA512: 543f11ed1ed6c8dbb3ca91cf09d56a5b215d7b1000657e167b71c61401f335e2576e40b0c3f8f7d3b69ed2ba4b081c859ee0a5ebfad4ad7867a1f19a01c7dd84 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9589 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-dds_1.0.0~beta.3-1_armel.deb Size: 2185232 MD5sum: d733e96ad5655bf46faa274551429207 SHA1: ba901af3879446fea292f78bfbc4d670bbf0c082 SHA256: 84e532174fb3ff4e391bbf7b7650f1ec174d6ab89e2c2f11788dc1069ec85bcb SHA512: 54bd84eab645c96f2ad3b90e19519021d065cd5a120932ebbc750c67729d88cba49d244531d5f8559e8b0a1a2cf12d22eb0e03a955683bd83bc3510d42fda5f4 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9213 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-dds_1.0.0~beta.3-1_armhf.deb Size: 2191816 MD5sum: a86e1ce50a2e561a72890d992cbf9541 SHA1: e1bd06a32f63314f307f0e47194318a90e24efbb SHA256: 69802e735ba60af7679e599c18fb15eba4124a074c660dccb2e5797ae0f4ab27 SHA512: ab46b68a47076b1671f2f1416cdbb48b8b2a51acb46375c679fe3f0e90e47c4d2d6047c2cbab10486d5961759e121f9792191c77d218a1a82987bf271af79b19 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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-rest Architecture: amd64 Version: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10865 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-rest_1.0.0~beta.3-1_amd64.deb Size: 2089436 MD5sum: dbdfbd0468f1621477475ab236336e42 SHA1: 4b3da63883f183abbd3132edef09cd5bd3345cb5 SHA256: 9a7a28ee02171cfca7558ddbe3dee1962acd0883535ebf0848332546b9f9b547 SHA512: 71ccece38a280336c6449f546300e275884426df638e1a10d2b55a98cb94b4782aae7ca3449fb0f66aafc797f1ecf068b6af651d954241b3c6259ba52e7a9f62 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9857 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-rest_1.0.0~beta.3-1_arm64.deb Size: 1913192 MD5sum: 920e41429aa599049dedb99a6b8aa727 SHA1: d988dda98e4b926f9dac133369ee49f095ea7e48 SHA256: a9cb1fb0915773453d50e632b28deaeb3c6ff22b12a43f20e4a40d8a890b5084 SHA512: 716863b72f3713cc302b4ae98d676596082217398e459a7d2f67619a3de002b3e3baae907ebbac02d6f159164a166f2c875ce5872f8495752ed2a95319cf238c 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7994 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-rest_1.0.0~beta.3-1_armel.deb Size: 1784724 MD5sum: 4ddddd11266a930170cacf02ba956448 SHA1: 234f4eaca60c14c1c8b22f1d9aa6c225f378eb0d SHA256: 4bc6522bc14e0592bb367920166290ade7cf517ac25c723b83187c6fcdbb50c8 SHA512: a3eb0cd07b983d9015e1010f735f84b0d83faf89bc4e967ed73b91a27769318d75c60e0b711b66b7534d5b51427bc2745aa686e2879ccd4e085bcbc145481d78 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7900 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-rest_1.0.0~beta.3-1_armhf.deb Size: 1775044 MD5sum: a04a3a67e5c85021ca45e892367ae5f7 SHA1: 36703813b4f82149d04167d863b2c1a96d0e7de6 SHA256: ec126b2ab0acce1d583586ea6e4753bd0366ca77748763b8e683025f0cc7259f SHA512: a821035220a876d8cbff7fd54aeb6530a18472c6daae182744c93aacdd170ea86d781b1505ecb34132860150a172ce15e6ee028a22cd9d9d48ba4e669b1cc053 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-ros2dds Architecture: amd64 Version: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13316 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-ros2dds_1.0.0~beta.3-1_amd64.deb Size: 2668716 MD5sum: 2152cc3e148bb16e0ca63a90a4b861f5 SHA1: 19e8f136344bc96cf3e4ad585fb1d3127cbb2626 SHA256: 862a67d1ee8f4a1a768f05797fc404e63a524a99ca295e8810222874940f2ff4 SHA512: 0d8308d880da8b213019cf4886a01e392ac85f6805e662b0bb66e1b021a31d4928aa5436d37f5ef0f7c7f55ab1aec33a11923e0f15d1f3b592608014e955a350 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12070 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-ros2dds_1.0.0~beta.3-1_arm64.deb Size: 2432796 MD5sum: 88dfc1b6564b6a37311d7f9c24004006 SHA1: 18ccc890e92dc570d7ad653ab437d762a5200adf SHA256: df7542ca2825a8152e1b6b8abd573103549b6ca9d41a6898ed71fc8068971b14 SHA512: 3b53fb073a1e73f87a11e2543d1fd766d5179a2e5f70afc3d259c2ac02d86ecca62ab43f6016546258bf07e388e5ec5ad19fe04b7782203351cc44acba9fafe0 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10121 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-ros2dds_1.0.0~beta.3-1_armel.deb Size: 2291064 MD5sum: d4743e2fcf6b09070d1c866a49f78536 SHA1: 6f836e2128391b364aaf0ff59960ace10781c535 SHA256: 6423aaee86dbed1359e6325a44f1b9301999dca8c02259286b84da06d7b8b58a SHA512: 9abe71837ef8badc57fca24d7261387ffb9222f615d8b95cd634d62b5fef0ea651143eb6cd130510cee27b14cb0168bbd6c869811a96ab8a6f5295427905ac5b 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9743 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-ros2dds_1.0.0~beta.3-1_armhf.deb Size: 2299772 MD5sum: 415a4c1c55baf7e7b07587438eae8294 SHA1: 791c1b08ba9350c9c1974e5b6637b41b21a72d38 SHA256: fc5d7b03fa8bc58a69fed2a558c25aa2179add26ac4ef34f75be88418f043abf SHA512: 4d4fcc593caeef3464df2a3fdb1c154dc5df979088704f7c13c3b9788b7847f7b06297e4cea34e4557a19ee3b3daee94e7f6b4669a28b8e172ab773a73766719 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10621 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-storage-manager_1.0.0~beta.3-1_amd64.deb Size: 1992860 MD5sum: d6b1cd7136cfdc0c21fcc54ef7ee3615 SHA1: f21769f8f6ede8eccbac90792f237d7978f24e8f SHA256: 2376d0c1428a63fa9fffe545bc92f1bf7b7bc169b892c0cd16934539d7de4b04 SHA512: f6ff60e624e114156c7939e412dca6ea93f86e9fae0b4bfcdf1b934ec00ac9e040bc98a42dab46b93b5c92efbb4a260831a5a67f3264a98039bcb9566a1c78a5 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9581 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-storage-manager_1.0.0~beta.3-1_arm64.deb Size: 1813676 MD5sum: 6066cef5912b58d5341b86b319c34910 SHA1: 95f6e49d548ed0b57a2207b108c46c8ee164b9d8 SHA256: 175c0003a7de19f7162be4e9ef7547759edd73f23408a587fbdfc9c9c2ab5055 SHA512: b0d79186c5eea35df139bed9672f4f8e99c5751620927f51a1b5e1148045f45f98e52cfb7fdd0873982eff3d61d9dff03424302628c310bed19ed244e76f1912 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7766 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-storage-manager_1.0.0~beta.3-1_armel.deb Size: 1709832 MD5sum: fb362b3b3bd182a1a0ce3417dca20f15 SHA1: 66604a1fb0d7a9ede96b92e0d9faa0349298113d SHA256: 09997b0094be241ebce97cf62e6520b0583b47a60670f7cdf4effd97cc891acb SHA512: df0ca102696ee68ad5ea1f6803c220ecba6f736e0513b21b7c6f39e69d5e93d494794a40a96f353403660e7280a55761ee38131d28bd02e39f5ee2e73846c679 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7651 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-storage-manager_1.0.0~beta.3-1_armhf.deb Size: 1695200 MD5sum: a6ad92ffd4dc849b4031a3b40052c685 SHA1: a3672fe0a03ceda362e16c2529311bebb3f00a96 SHA256: 032c946cff80190a079d0cf5ba8d82ed6728c5840892011ee49c6818c5c36929 SHA512: c4f5f44aa4204a306b72540c4dfe48c1c62c5a4232bd5b0ef35828ddc795e9be1e40fc2b21a096eed22b1f4db20ff1b625c23a6c5eb4b1b603df05fa6204b195 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13314 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-webserver_1.0.0~beta.3-1_amd64.deb Size: 2526896 MD5sum: 334b4a53a268bb1b60b7c138b36f862f SHA1: dd3eebd08d83ff30f82708740e3fca39fdc4fd22 SHA256: d9981bb54089630f8ebeae746ba10fc901e9e62f9a53098fd92e7625baaeff01 SHA512: aca607b484b3c3d9dcec5fd45f42115a6f9c8ff22fc131e8d906f1dab38bfa99e3a6967f0375f0cf52486dda033c66176d49d2f63da90be75a20bcbe6fbc23bc 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12552 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-webserver_1.0.0~beta.3-1_arm64.deb Size: 2358232 MD5sum: 4f7ddc97b19b4b758428b9029b62062f SHA1: a3b074c4fdf1f5ea328b0a865e18429f82d9fc41 SHA256: cfc59c028b0e18b151fa54b76f6c859ee8d26adca4057b9f30085f30edafe144 SHA512: 332c5ae209dfadf3e1353d22664bc8627b1187b7f582a1a2b8912dce7ba67a2fba3d5c5a1162e9d71cc065ac99b95768d57fe49312d0f6fec1ed40dc545e5f7f 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10229 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-webserver_1.0.0~beta.3-1_armel.deb Size: 2148828 MD5sum: 2c8c8bfe62699db80c1bbbd4b24ad854 SHA1: cd325a380f75894be024c59861ec895309dc359e SHA256: ff8aea4543f0b35239da4109817719a1949e3e5287b6fa7506a647196afa748d SHA512: 031b789fe887b4b86727c1d357e98a6de557012877ee2015a85790028700cfb62d38052323c6750f33a6afa18fb144364b3e9bdb2ea99b8f9ac02753af18a8c6 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10098 Depends: zenohd (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh-plugin-webserver_1.0.0~beta.3-1_armhf.deb Size: 2135636 MD5sum: 1676529f6839ee28e852672ad900e745 SHA1: 6299b00746ede720e00586aad7620f60cd24362e SHA256: 3518cea171af7f3deb6cd6dc4c03e9f30a0e487ec52e49b070fcf55bad633d21 SHA512: 14f395c7949e1728eb1b8d4c1c832f8d621fd74ed8618198f98c3c712593e57d34573f6370ee5a30857f31e366d921d891c4c30e6e20d2a7abd81494246c60d4 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~beta.3-1), zenoh-plugin-storage-manager (=1.0.0~beta.3-1), zenoh-plugin-rest (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh_1.0.0~beta.3-1_amd64.deb Size: 17344 MD5sum: d690399dad534f0c4d0de00e086fdc87 SHA1: 9c39bb4302eee87f7a87d701f41449f535260ca4 SHA256: c5b2848971703b6d20680772455707788c0da0c93b52206aa051cbf4d94d2f17 SHA512: 493f157d996fbf12031a84224ba3789b592fd430d1d567fecac41ed937a4882ccf4f29e8d0e6c1aebcdb8d72198987b3fa27c4a1a366b20dbb2b6b2b55f18d8e Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.0~beta.3-1), zenohd (=1.0.0~beta.3-1), zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh_1.0.0~beta.3-1_arm64.deb Size: 17344 MD5sum: 606d7e93959cebe0404dd4d92916e128 SHA1: 20c9e38fc3f8d658c6943fba22f171d21191e52d SHA256: 3ca378a42ba51f219858f2094f19c53b848e9327df13ff2aac1358124ea25898 SHA512: 5c5b014eb2540e02de519b67f6f5eb0c351ebe413a8f06732476176325febd65d8bc46077cc29c6ccb26a627573a60a34beb7b07a4ab649222ebf26f7c38d7b5 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~beta.3-1), zenoh-plugin-rest (=1.0.0~beta.3-1), zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh_1.0.0~beta.3-1_armel.deb Size: 17344 MD5sum: 6a2aac917f1384d05db2bfc7d4b36c23 SHA1: c953ce3aefa6ee04317a81f114384671b0973823 SHA256: 5ca271c5ac464f974a34538b37b84c00b4222cbfc2ba4e1adc50a09538da0106 SHA512: c90c9d1ddfea025b7a74da3a03521c33243d61b398f3ffe3e4e732e5343ca842be63abd8cf555ef650dc7126aa8b6726867cd598e1aeb4a69de0c244cb7e2a37 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~beta.3-1), zenoh-plugin-rest (=1.0.0~beta.3-1), zenoh-plugin-storage-manager (=1.0.0~beta.3-1) Filename: ./1.0.0-beta.3/zenoh_1.0.0~beta.3-1_armhf.deb Size: 17340 MD5sum: be36d00d74a517ae319048e6ffae64bd SHA1: 02008201a8bc4ed3a2026621306a33a1ba93ce5d SHA256: 7546b9c905eb91276c343dc591b4d0274e7e838c711d72f6e093fff3464ef0ef SHA512: 7198c407b51e78a3c9cafdb4d5d1e029adc67d646aa75fbff837f8cffb4611d4084f2470ea7a583512ad2a73247ccc28d9aeafcca104e000e82982b8e1d5d3fa Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17937 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.3/zenohd_1.0.0~beta.3-1_amd64.deb Size: 4399952 MD5sum: 26c29e184828b5e7ca0a7ab69f9519ad SHA1: c6d354ecd8fb12cc73b9a7987af4e2599635d94f SHA256: 9902ad888dc22607ece66efc3bfab517e8f15e86343a12c6b016b27f49bf567e SHA512: 5482542c5f48a2286bb0c74d381f93f6eb9d7260c8e40a65338812078bac44a41cca87118a3a50cf11c20904cd71ed7eae11783ec0d01186063e244a50e4252e Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16083 Depends: Filename: ./1.0.0-beta.3/zenohd_1.0.0~beta.3-1_arm64.deb Size: 3951932 MD5sum: 2064c9f408097eef6566a7d3b09fcc24 SHA1: 5331b952cc90df77ee8351a8b7c2d66079c384ac SHA256: ede6d2f8ed368cbc1e2313029e440edde02691eabe4b6dafeda45bfe18b1e7e7 SHA512: cbad45e0733881990a59544a3d04e4da6ca57312fac3dd11acd3315e3fce6be316e9d52ebfae214fed7ce26b4bbf29e3611abfc736ea9f8684627efeef6b4405 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17424 Depends: Filename: ./1.0.0-beta.3/zenohd_1.0.0~beta.3-1_armel.deb Size: 4297512 MD5sum: 54bc5c00e95d8073370b845df39fab44 SHA1: 3b8d25e05c233fa6c9fd5579c4cf1e5e43637ed2 SHA256: 1936bd2554a398a4ad96ed3d4440c2785b1a7762c48fa8c8a16f088e2f3351a7 SHA512: b3daa57bd452822c7a222a5b3d474e24eabee93892ee38e3280f595dc5dd3610fe02ec6eff339d74e42ae82fce08dbb6b536c28dc4d33c6b7c33f5aeab894f3d Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.3-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17211 Depends: Filename: ./1.0.0-beta.3/zenohd_1.0.0~beta.3-1_armhf.deb Size: 4351644 MD5sum: 72e91bc13ef9771d34b551e872009477 SHA1: 620fc046cfb1bf3dc7ac8b554d921528b6fb8c7f SHA256: 9658cd8de396e4ce99861de44234b592bdf4863e25f60cedea3476bebca5d6f9 SHA512: 29c107e083d8c3e750c94df9a584454bddda4f06a0514660302eeca89b8f7c042e7d9d23e99e10f4ca752a51d106f55996373e7e21e279a1cbde0a97111bcd7a Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20835 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-filesystem_1.0.0~beta.4-1_amd64.deb Size: 4600308 MD5sum: b66f1a1ad3fce3586f3bda82369b7188 SHA1: 5fc223c8faa99efed868e89e003aef51cc081a25 SHA256: 179765fb672457620c4192172aa562409bed0793fe981cdc130508d1d4b3573b SHA512: 678682fc8f409369cde8ee77812105669c87c54fdd2094c532217aeee5fca010ab02e7d008bc496704d2de7773121e9d342f66966bc90d0a4cd7aeef3c2dbeb7 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18941 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-filesystem_1.0.0~beta.4-1_arm64.deb Size: 4137536 MD5sum: 798dfc7eeb9c3411666d1d8610266449 SHA1: 5413842222923385fb6691bc3f6c2bef15363179 SHA256: 0963faa9358ffe50252fd79311ee457c6ab3195c8ef33c158cea9e68e2a5987e SHA512: 05492f5a2a1827315bae10c4288288f56f54a2c5e02cc2f3c19e396ad2019e59ee089ccdeeed27fc62953bef6f3632e65459d4ab6fa1bc76f631592aa9be852c 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16517 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-filesystem_1.0.0~beta.4-1_armel.deb Size: 3909076 MD5sum: 7d4e180457d39b96e252af48a17e1585 SHA1: a56dce6df5451cf62e10867066c81fa8a11707b8 SHA256: 5d157daa919c1a3cb29c36c2d96cd786a0738d3b8874329f3e6e548b1c74b443 SHA512: ff3242a20212836d1baae3cea289ce0a65e3f7b83b9f14d27bbdef1edda779b4f51209422684c6447f04246d4b1f0352c181c403d7ed43e03f59eab009e54263 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14632 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-filesystem_1.0.0~beta.4-1_armhf.deb Size: 4006508 MD5sum: 5461d3989974f42a5709902903b41855 SHA1: 90647d335ba6331300f050aecb7ad6526cac71d6 SHA256: f55534c1d9f309611578c12da8ceb5c47d35077c847f0f497555f881ff0668fe SHA512: 7ca15598bcc3e077b00947681fd80abeab1c731877031cd564c7027a5c96f50ee18c2037c9e2a9d84b5bcb5c1c235a91ce2a8cfb992777ea2783c7874731835b 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15711 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-influxdb-v1_1.0.0~beta.4-1_amd64.deb Size: 3129876 MD5sum: aaf647f7759a3773df79cf636ed221a4 SHA1: ff4c1a6f09536f0b8209dc475fd5aeeb4c6e648b SHA256: 951fbff3b39707a87ff87673649344b3006e49208aefb28abc319fe52a4da78a SHA512: dc6a99fe7819b6e4ff393c5c2462acc8777f5ca1451cafae5550a14e4328976bb16a3b1627c8563df49cb1b791ee3dab73ec9c64ca21b552d0c778c1ea891741 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14028 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-influxdb-v1_1.0.0~beta.4-1_arm64.deb Size: 2814348 MD5sum: 69c95673cc4716b18fde8e6caff1e342 SHA1: 94435adeb8cec4a555cd062e0b8d973bcd2aa115 SHA256: e62ee75018bb4bf2e43732153e04114c65c188efb483f170287d0bb386bdedce SHA512: 1b9caf4bd150bb7c86ebba569218068bf01ee651482196a14221f81f7960b7fdd2911199546600f9e05fdff0752c176cc9c9078731c9f1768481270e078ac493 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11805 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-influxdb-v1_1.0.0~beta.4-1_armel.deb Size: 2551944 MD5sum: d73382090f4126b01c9240710644c0be SHA1: ed7b774545c011f79413809985183e717494f458 SHA256: da5184b5e172e0009db52aec44051412568dd067fcac59f78d7099438359977b SHA512: 9bb9513e8750476e7ec5f8a5895bfe0a54959c3df08bb262068861a9b61e4e9590f64d35d2e97b1a3d104699710ba4ebfda4b37123cc70b2ab837902e54c0df6 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11682 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-influxdb-v1_1.0.0~beta.4-1_armhf.deb Size: 2545608 MD5sum: 17a0c04a62e4303be5aea1188563f2de SHA1: be048c7b9788d4241aefd8ce5ad2749f140e5a83 SHA256: 14cf2548e5ee7c94647410a64d49184998614f2b733117b5df77bc93b6384401 SHA512: 80ad86884d5aa90437d8b370bf0df3091504355dffa2dceb7e5c5dc37c709f6dd214f0f0e486243b9f5d48a163a476e54336a122d45ee3fed0ac721ee7266580 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17300 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-influxdb-v2_1.0.0~beta.4-1_amd64.deb Size: 3802896 MD5sum: 4f60d6da333a3bd2db2949cd44a4cc3c SHA1: 80a7c82edda668c187177bfef631d757e790e910 SHA256: c28011eb8dba75ec0bd9387dc24a079dca02ca305306fce55a6e8f0371b0d88b SHA512: d7716d26314927a10e24329069955a15f7e1be45eaea867610001f7b68abaa831e7cacc8c5f4c363f52a7df0a44e587ed9533109595b9d71ad0e2dfd67bd6f38 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16273 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-influxdb-v2_1.0.0~beta.4-1_arm64.deb Size: 3485448 MD5sum: 508cbf335773dccb89be101c4c5098b9 SHA1: 94fa2aa7f75b8af3527b275a98c65835e9e72a9a SHA256: 1bee427c3d46c60ee89866df4a5942aa3c05794efff54a16dff190808f897276 SHA512: 9db8069ee7dfb859c467797e75ca585e7f2df0bf749ce61c46e99468a3738f16b106a825e60f95251dfc483aa746b914aadd72bef3a40789e3c06ae19bf684ab 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15596 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-influxdb-v2_1.0.0~beta.4-1_armel.deb Size: 3468680 MD5sum: 237c18c0f0e55e1c0e69ceb71d6b60c1 SHA1: 396b016c72ed6a8626afa3cf1300711a57bd6012 SHA256: a40b77b08ba54b3c37708b9b01940109a351f4dbfc7fa0602921303232eba164 SHA512: 238b9df1b2324129d4a0491633f39ca1bd13e53f7359b17eba3b80d48727216f7214281a40c6f8b53419aced465ac0aec8c51b91ea2cf00d6b91c03062dc038a 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15490 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-influxdb-v2_1.0.0~beta.4-1_armhf.deb Size: 3511452 MD5sum: a75ec29c3d0330973bba1fd80c6b0e9d SHA1: caa27b95fdd5a1cd40ddd136b78563e35980cf17 SHA256: 51efd233a734dbf904a723ef52f2cd94758c14e2c4951227ac7106af3ad68ab9 SHA512: 5bed55d770d04b5e24b21df11f1c5c3cd45be882aeb8880a3b4670ff5c1358c7463b8cd6ec8e92958fd33cca7804716454e26a9ba91b14fa50ab14025601fddf 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19399 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-rocksdb_1.0.0~beta.4-1_amd64.deb Size: 4330772 MD5sum: 8aac2a569a1ba5ddbd0d53c967bf4282 SHA1: 079ce89825165c98ec68be38490995c1fe745adf SHA256: 429aa43b182dbf9fa7d7fa6d7160098e0c871de59f46605a44ec5e5d1f54ea6c SHA512: 43e754ea37d0811d605b76459d9c1680c5cbb1dcee5f8db37f4280b6f382e273b5390414527d9ab999df5b1a0c028a69a5ba960f97670d77be4ae1436808998a 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17507 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-rocksdb_1.0.0~beta.4-1_arm64.deb Size: 3890208 MD5sum: 18341d067ca058e205330bf2e1b85dc8 SHA1: bfe907ba6915d1857a17f7c20ca6b0705f75867b SHA256: cb6f198d3ba7b7bca41afd57a84d6300853c64bb97722d5c0195c7a8a8dbd53b SHA512: 59e8f87e48fce8345a471542b05ac6ed51bdfb7685c5ea0fce022af5dad84797d6b1de448306a25e9c74e12e99a68698d8611ff4d1c447be1dbe62197bff8d6b 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15318 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-rocksdb_1.0.0~beta.4-1_armel.deb Size: 3697728 MD5sum: a8dd341dc11efa3dbe0b4c741776d6d5 SHA1: 059c41f16c88d7d332501bed469e00058bce6874 SHA256: da2513f903e3a21d37ac254823d44e73807d7e08e5efb412745f7a7be97fd82f SHA512: cdf09f7ddd86e9c1064f43de973279dd69246ee49b0a1ba66e7b77bc004c6ca63efe0d6b571977431fcad7b60905f8c7b6e4d1a04afc8070e528da7288bc38d9 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13411 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-rocksdb_1.0.0~beta.4-1_armhf.deb Size: 3798768 MD5sum: b93e6ef8768060845b87f2b2a3ab76c8 SHA1: e4e0e742c876cdb96dc9afd1acedd275333f3711 SHA256: 36713458982668ba686f45cecb2867f2a708cbdb6fc8e2395801032cac0f00ec SHA512: fb29f497fc79400464bf4f78e658c3e3405ff2314e22d3d68551285f1e644264534c4ecd2d992ee563794b9b4589a392b105dc523ffd56b377c893d2346be0b4 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27235 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-s3_1.0.0~beta.4-1_amd64.deb Size: 5510120 MD5sum: 488133bbef878928e26c5d9996c46615 SHA1: 6ce02cc85d31dd44615d4fd8baab08dccba0706a SHA256: 9dc34ca9e7b011a19146e2568c3e809ca0acd322e3c9bb510ae279b0f36d3477 SHA512: e8a2975398c72bd29162da66f3761046fee627236624d86371af53451d017e08bbcddec6c8cb202d9993ddaaa4be6f75dfe200b18c812f117da5d6aed8696b46 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26478 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-s3_1.0.0~beta.4-1_arm64.deb Size: 5223448 MD5sum: 76775a5da984e5b6d85acb50e469271c SHA1: d14137cf946d560203d47434e30551f2c85a6748 SHA256: 53d4aa9ce5b2ed604bf80d97ee150780bcde322223d342211fcbd61746912d19 SHA512: 098f81dd84b1877240eb331e6daffbca0f8a8fedb9900d97053a356b5e4bf0b9256229a7ba24885fde7ef8bad2d7f08fa931370247fd95e15c4688492e825a95 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25176 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-s3_1.0.0~beta.4-1_armel.deb Size: 5098992 MD5sum: a2cd67b1775159df9406ed70f079870b SHA1: 7d6b74702fa5c5cb1500e23c776a2fb9a3e41a5f SHA256: 88564572601ab35920a51ba73d4d7779181a4bd53f04bc32b7a25465a1f373b2 SHA512: 074236860e2a275e3d11251dea13a65684b0e94b27c4ea3f622266036a8f45c453d7180de40cba3e4a0ce1e168cb446476acc5fa63d2b083dcf1d8139c19ecef 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24946 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-backend-s3_1.0.0~beta.4-1_armhf.deb Size: 5138012 MD5sum: 24aa9aed6d4c1c5dccf065fbfd16df71 SHA1: 5d7827b7237dd77e61d6a986ffb5c82361afb220 SHA256: 447f453003daaf50bc93d4fc5c3abec384aaeebb6a4f482ceebf36bdfdf3ec46 SHA512: a54cdac125156c2771376fbac275a22282cae85d5f72471317dac2e48bb6c70defee32773ef8d749c17952ab396a28344459a5f161e6fabda0531c421a1bb294 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20560 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.4/zenoh-bridge-dds_1.0.0~beta.4-1_amd64.deb Size: 5270340 MD5sum: b410ced82db6889f498563e88b60cc28 SHA1: 41f261e4f272e1e0052532f965cfa1d422353523 SHA256: d1bd3d63496e1abdba03a14bc965a969f22e494db90416ca3400050ffdb59da5 SHA512: ba6ee586d9ceacebafe2580b204279f99e2b9d40e209c41d04b2f4734724da1728db00dd6bce0e404b243cb985943907814b3149642e6c9d6fabef97bed4e577 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18789 Depends: Filename: ./1.0.0-beta.4/zenoh-bridge-dds_1.0.0~beta.4-1_arm64.deb Size: 4764556 MD5sum: d4f6e55ec4e954b2639258b424bef41f SHA1: 998d923999c7f36b6ec8f9852be3427fdea8da58 SHA256: e0caee8817a6622742375034740e102cd25db8f0aa0479613d6dc1a99472be4c SHA512: 3d5efdbf3fd8612d51c84b0c2aefac2412a840f2931ca4435adf74af956d849e78216a343acae3b25e00bd8b4091c4d244d10630a0a026d5b439cd1674c840c8 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19927 Depends: Filename: ./1.0.0-beta.4/zenoh-bridge-dds_1.0.0~beta.4-1_armel.deb Size: 5030264 MD5sum: fa2ad30af35e9b1cf9b6ed78d869cff7 SHA1: 320895d7bdae6b15972f82d46ee7592330c89b95 SHA256: f27e96922e8396d5f31dfd16fe8680ddb72b7c6f9a79f6da7562d3240fbf5806 SHA512: dec87672bc682074844ca7135add75063edd694120e83cdaf7b275e23b7c399afeb34a0d5fafbd005ec2efe8bc6e999293fa53205544a60942923839501747cd 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19414 Depends: Filename: ./1.0.0-beta.4/zenoh-bridge-dds_1.0.0~beta.4-1_armhf.deb Size: 5079416 MD5sum: 362ae98d639a1cd15653ba4c0a87ec1c SHA1: b6d96348a2f22cfda559686c43e822f55ce98ff1 SHA256: 8d66f2572c4e1773860aa6dae3203375ab4b819a7af7150c18bc650f59a65906 SHA512: b87d5d304afeabf696e4a21617e3230844a1688fc247b7fce879d4fd5e72b3d5a953e77d9f7af0dc01a28f32ccef7b6e4acaeb6dbecb5d01e9bf50d456a03af3 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20498 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.4/zenoh-bridge-mqtt_1.0.0~beta.4-1_amd64.deb Size: 4941500 MD5sum: 7b932d56bac62b5583bc71323a7dd0db SHA1: 39278131b1fb02df60a21f1994494358e44642bc SHA256: 159ed5bcb9f5bcdf83e58974c17c7063aac643376809c2f52435c3b583c1f513 SHA512: f938ebfb3cb12276b6a743d0254ee8299ff66c0425124e80c1b17a01475732f4660d6f47be24c46b2490a8ebe9fc2fdc67ef37badde763354fb70bf8cd801d8d 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18717 Depends: Filename: ./1.0.0-beta.4/zenoh-bridge-mqtt_1.0.0~beta.4-1_arm64.deb Size: 4465636 MD5sum: a12cc7f4bf85126a59420d8d340fa0c2 SHA1: 6d74fa7076646d408afe213ea56f61d159d5fbda SHA256: 02ec8667975974b33a836af65101c0c5914e8eb1f4de2ed4bc6dbe03d06222eb SHA512: c2173cd26c021713009c28f0911441feb0d79665ed7c416cb2e170298bd6d3cceb24d041f954009baff5424e43265cef6cb7cffb1facf38b712270c76f711e02 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20031 Depends: Filename: ./1.0.0-beta.4/zenoh-bridge-mqtt_1.0.0~beta.4-1_armel.deb Size: 4752924 MD5sum: df76381d7c9f7e32fea4d135fd721567 SHA1: 5e48ff202b227eff5cceefbd551aa73e3670bc8a SHA256: b9126f6a5967ec1c11b99efc192342fcddb6930924cc5989e2e2884884324aa8 SHA512: 17280708e4ad2a27b80c4b08a0d51fc9bd138ae9fabe4b967422ac7846f0d9d618e07cd8632bdf50990c40c01bd0e0ebe444df24dde2a6d6a0bcf0dad116ec99 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19756 Depends: Filename: ./1.0.0-beta.4/zenoh-bridge-mqtt_1.0.0~beta.4-1_armhf.deb Size: 4785664 MD5sum: 6547cfadfb9df7729c5cf3d7c04a31e9 SHA1: 2cba5ee1458a11cd69a80f65d0379c5cc14915d8 SHA256: 4ff62301402de54d74ff65d437a56482379fa60e0f72724e2b57287bfd4c6372 SHA512: d42357e4585711c8ca4e7b20b975e576ca1a2ad3186ceb6ff3df51f3aaa73d0246a6e4653f3d75a9424f3923ff206eab45e7b82498f5dcfca1f7452aecd2b052 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-ros2dds Architecture: amd64 Version: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21121 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.4/zenoh-bridge-ros2dds_1.0.0~beta.4-1_amd64.deb Size: 5368792 MD5sum: f291bf6de068d1e785232c0b2bb296bb SHA1: cca82a2edbddfa6d20c21b4a8034548499dc76fc SHA256: 5e5adda2fadcc033cf841702e1d902af36fabe4e1135639be46fb2d966944de9 SHA512: 9895e5b6438b435b67b2ae2e13b16f1f3ad981a24f8440100127d4ec62d35b6413bfb1a15cdab6fe25041db004d4ffd907731629d7cebc55b852113f6b7e2c10 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19309 Depends: Filename: ./1.0.0-beta.4/zenoh-bridge-ros2dds_1.0.0~beta.4-1_arm64.deb Size: 4868904 MD5sum: aad264ae679d03704221bcb76dcf4e2b SHA1: 458fce96df8a230fc07b4e8b5d5a259e63449883 SHA256: ab4c3f3c8b7483da156a5b813e9e56d61e68d83528c3286871e288c6f188ba33 SHA512: eb501be45647cde2516f7c8958fd4bf585e077428d482bd0ddf67db57fd1c18b631f9acc650d42e49a2affb715dadc2a3ec415a07291ef7ba97ff8b268742694 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20459 Depends: Filename: ./1.0.0-beta.4/zenoh-bridge-ros2dds_1.0.0~beta.4-1_armel.deb Size: 5140704 MD5sum: 280fed9ddc5eaa07433dd7f2e82c0001 SHA1: ee90d8bb559190d82183a9ed353dbcdbddb7d21a SHA256: 94cf0a6e1392d21a9f5a4aa933ba4721aaf446b867f619df72610d5d988254c5 SHA512: b65b523e7ed7be28e1eaa41a5d305688833d500f68108b42c677bf0e773dd7b47e6c3bf59a7f8f4018189d012850bea900700c3ec5d431276023b1f517843635 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19952 Depends: Filename: ./1.0.0-beta.4/zenoh-bridge-ros2dds_1.0.0~beta.4-1_armhf.deb Size: 5191272 MD5sum: da87dbda535bf2622a8f8c3d88b5efd0 SHA1: 8921b0661ac95285c442a44a9a8f18a250b12eb4 SHA256: 69c8abdaef0c3b5bb721633705a056aa5cff973317c91369c4d92d126b54c176 SHA512: 6e31bdd87934f64b92bd779f43008c0e66ed0927d797588f7c977f458a5a509b4b1919aa72e3bbaa4965f0ccf55abd9fdfd6bd757a257e504af4422f7593e7ab 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12746 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-dds_1.0.0~beta.4-1_amd64.deb Size: 2569508 MD5sum: 663e820f6ea8108286ae2527672f9a6e SHA1: 8bcde4509ff8c741158a4e496206922c54cf31be SHA256: 291502b449cd29d976e87f79f58ebf055e52e99c3516cafcc79abdba82e97b06 SHA512: 7a08bc2e88b6a93c2c4bd295929a11664eba556786d80f109ee24c2b2f2d390a96fb3e0874bd19209a6cc5f43bbd75fb06c2a81ea174504b4332cc2c6324d641 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11548 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-dds_1.0.0~beta.4-1_arm64.deb Size: 2336648 MD5sum: b06293ece2f15b1f9e4652f6212baeb5 SHA1: 368d2c2e12a5ec58438529ed95679ad9a71a8e1c SHA256: 42ad2eec83c9135d079b38f315e62ee6d0894d45f30afdf76343bc305778deff SHA512: d24f9d5e93fd564b5083fad4e8816c6f7fdc1868650c848bff47254c9aee5ac47298e236366742c1fc0ad817507452365ea7f2ce428b893c25d5adcc8bb92ad8 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9574 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-dds_1.0.0~beta.4-1_armel.deb Size: 2180068 MD5sum: aac8936e62584644f468f588aa58331b SHA1: 76bc3f440448cf1f5565c37c3b83de37aab02b53 SHA256: 017c6238d7c8fa7df0093d1662574683d4b0fe53b0685bb32c29faffdd11691e SHA512: 98a814f92dc39ea9a0829e1cd3409de70b5b6dd8c5ccd4dbf1b51f46e50028c90ca039696bcadc64471c79f2b75c309d53d8a4cb91aa76273163f41f95ea134c 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9200 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-dds_1.0.0~beta.4-1_armhf.deb Size: 2187952 MD5sum: 0b19d521868d9a8ee4f0c6b0621d3e5e SHA1: c053203c956bc5cb0ed8f949fa3320b4bbb1827d SHA256: ca16d33b8b43341b824806aae3490c64de24597f7f7a61d5f6c754b860a04651 SHA512: bbd422c9bc9741b2993f61b8f25fd37af591ac05e162c4d8f01cf0b52fb9e0eea5978a644e8c0d7164b4e4b833081311e5d2a8dd461fc785f038153b4a4105cf 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14073 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-mqtt_1.0.0~beta.4-1_amd64.deb Size: 2885072 MD5sum: ef93d807e239f74ae5b7a19f4059a29e SHA1: 2e65b08b63450e19fae0c606888b0053c9937844 SHA256: fd116d9608a01b6c712fa5196ddf6c910105f7e9bf6be2f290fe2820ece8dd44 SHA512: 189cec24816f15580e32d166e56af5f573e17350565cf1fd5d26f99a14066557d6d359cc3671db1409fc406737c7b22bab03247888a1f9dd80c6ae6771d7ca3a 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12775 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-mqtt_1.0.0~beta.4-1_arm64.deb Size: 2577140 MD5sum: 14cbe8ffa5543327a6e8e7b2977384d2 SHA1: 6491f810c609c00f9e832f85107f61bebf189450 SHA256: 9780290c278dd8b4d496a31c306f60e6d2eb408e93b7317eed726872b2b694bc SHA512: ae1e4021ddddd2498e52c169ee454d2e9586c2c85726b1d2cbe329fc1c872fec841dd7ccb1edcaa0bba5657a86c20f95ef75265a918aad90b0cfb00fe0c9d849 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12787 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-mqtt_1.0.0~beta.4-1_armel.deb Size: 2644576 MD5sum: d08597f0be1f11a1c3c882d8c58227a4 SHA1: ad498f54d56806daf2fd5dec3b459034e9c92091 SHA256: d70f0c6d3ad71c9e7157467bae6935b717056e12b2c165324a5e2e4010793466 SHA512: 3c52a71196a57a8dee9a4b25cbfaf4d33a41d1a12a398322411e272996e4afd7e8800f9207f4bf6858928804cd81385d399e622d0701787b71085c18b4ad44ed 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12703 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-mqtt_1.0.0~beta.4-1_armhf.deb Size: 2688180 MD5sum: a098f94fb1fe95a6ad625785052708ae SHA1: 43dccd6249c5277aeed9522521b4ab7c69af8965 SHA256: 4bede6069bbeffb98390f2101445c60aee0896a4627eb069796f053c26978c4e SHA512: cb07b199ed3fbd03af7ecee23b154918648f83edc965e3982a3284bcb0e8b5862ad9b666d82f568ca06295526bd48c658421bd4a5a14a0b4da5d3c4dd765f089 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-rest Architecture: amd64 Version: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10857 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-rest_1.0.0~beta.4-1_amd64.deb Size: 2087104 MD5sum: 4c187b06e36c71ec7e6d30894466bb74 SHA1: 0cc3fad1765bcfaccddf986620b123487b004db9 SHA256: 1ff63e190bdfc78485d7c47c0cf176c640aa95c862ba943fa2645f64ae0b8f7d SHA512: e9f6726a19814a2900d474bc7df51dd9ed69318a57127c5c82182a3e5edaaf4014d3f7a19c46e6cdef406c4065ba2815e42dd723500c4d0a86a7ab707a6f7f91 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9834 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-rest_1.0.0~beta.4-1_arm64.deb Size: 1909592 MD5sum: 1e9099deef51cfcda9d879a6cedf7c84 SHA1: a617702adf0a091c38740e9aa7148686c5cd2001 SHA256: 1ddac5ec53a04acc2279d6b982ee98a5f9d3fa13187869481a861c42904f0365 SHA512: 6967e160ad9ab59d138b8e27f3d31f236f46f84f0018ab0b994f987d80bdcc25753689e406deb62e07a5378c8a476e24b17b1e4c0a79d9a9bf6c1e763e0c2fb3 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7980 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-rest_1.0.0~beta.4-1_armel.deb Size: 1779316 MD5sum: a5c62cb7975a724c997caf03dbb14271 SHA1: e9d12fae359fc39992e822c60318e30dc009a5ad SHA256: 613183f2ce00be7e30e6272cb64907e59cb5de91ad7efd48929ed451e00ec073 SHA512: 06bbc65d761d1e78bb89aa4dd2026c281d3a4143bb8d3c409f0b451badc99c9bfa912ac3b47958d61d3cdbac1665632dcbf6fe725146b7dcbf10d1facc7f81ec 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7886 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-rest_1.0.0~beta.4-1_armhf.deb Size: 1770080 MD5sum: eec4be557577fe0b608daa21601d16cd SHA1: d963b0f528f765f4ebf841495c3e519391490828 SHA256: 4e58094173f60af4fbd543394cd2bb44fc93a06965050e43da5f97a91d0ea5fd SHA512: 75a8767d9364ae81466a1da4854c7bb65e46a6cb7eebf7011d2d1b359f246fe6ad0dd53415a57408f824c48bcdf121338e38a095adc577c5f825325d7fec0e97 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-ros2dds Architecture: amd64 Version: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13293 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-ros2dds_1.0.0~beta.4-1_amd64.deb Size: 2664212 MD5sum: 91daee2ac860b0eb7b70e28452bcf0ec SHA1: ccf10303405c8a9ab3d9d292bb999904a1c51295 SHA256: 3d092a9452df40b08b6a7ea390373e8760b9cca720d95ecbc3163942841e73ac SHA512: bc76da3477b07835f43fe8799cd26ee686345111b303769851696a8ab782d3c7145eabc6943eeee9194193608361f6ca87ea7da0a03504760e9807122af8b2d5 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12070 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-ros2dds_1.0.0~beta.4-1_arm64.deb Size: 2428352 MD5sum: 8cee80fe12b0179ee9fca6ea03f6058a SHA1: ebbba4b42b4c1ddc311a0015afc03a14630dc7d6 SHA256: 429631f09f11d9ccc24cddb57f0444755a9dacd6b8006a877b0559f115a0237e SHA512: 61f3049926f643192d2577405551c986cde5dc1a63427f54c24d49150b1fdab6797218cddd9ace760f861fac594f5b887ccfb99adeac99cf5e7889431d0cebd0 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10095 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-ros2dds_1.0.0~beta.4-1_armel.deb Size: 2283636 MD5sum: 9f5fdad5caad6013f0c10db0c8777278 SHA1: a93721912b53961212b5be3263f2efb3b8ad17cd SHA256: c300701c03b541caf6dc79e7bb11103fdbab176e268b9bfadc235e27d84723f0 SHA512: 72f9e3358edcbc6abd4eea0ee6d54404e0b9575c12bd4ef9225ca979419b9e3ba6918e5f6f9bf1644ab746f6f4408d8470931b404bcd7104e8ce6372588041dc 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9718 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-ros2dds_1.0.0~beta.4-1_armhf.deb Size: 2292512 MD5sum: 390bb250f06fb6c4b7b8da11f5295ad5 SHA1: 5eb36becce66f2089c878c2628d1deb02211695b SHA256: 71966e153a2cb92d4c275c8f410d3c3a1073d6db3de2439030c2a158ac4387c2 SHA512: b14af06b3bb02b6109325ed7ed5a36906b1654d03d23b5ad57f93ec07df51382612f7a64cfa2730086fa93edd306a306dcfc804e6f53dfc25d10a3baf77a5c1f 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10627 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-storage-manager_1.0.0~beta.4-1_amd64.deb Size: 1992468 MD5sum: b8e7428a22dd08979b278e80a72d15f5 SHA1: 44b2627e6aeb9a1670dc05da2d4c64ab1aee1877 SHA256: b43f61a2fc25d7a006946d4705f00a57de14d5edb846c1eb36ed276a65d14e98 SHA512: 1f74d9013b55a4e7d4af76679c0d67d08cc8e74c98955c86dc942cd02885ebea25f96b0d06877d7146fb92def5fe495a303dc66c7452bdaec719bd2f65dd4b96 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9585 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-storage-manager_1.0.0~beta.4-1_arm64.deb Size: 1814900 MD5sum: e3f544289ea324e2bfe089f4843cc3cf SHA1: 7629fdf0a1f795c5577d49e7fd58d5583037edb6 SHA256: 03c794bf2af011e8f64bb59298d696712afd74e9af572cdb051bf61112b72c60 SHA512: c96bdc5f1fc3f9b968cf9d457c8595c5f83f1c157ba629394604358f91e2ceb178e22fd827ae774cc26433150bc56347385d8e2d6b592bac146fe1f2b5dc32ee 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7771 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-storage-manager_1.0.0~beta.4-1_armel.deb Size: 1710996 MD5sum: 6ed0d7d6c81683db1697b8c9116c2467 SHA1: 5c26e81790e02e7e8c01c1962e415def3694e893 SHA256: 45b462067257f152e36e6b1095cc63f019231ff55bd6c150245cfcbfdd8d3823 SHA512: 49d0055170557813d3d8441bbfe97560ce6ee6e2eafd04c6f3fb5a687d4ca66d6bcdcf1ba12898f197468d965872caea923441864234b5e6ef22cb5063936045 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7659 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-storage-manager_1.0.0~beta.4-1_armhf.deb Size: 1696624 MD5sum: a97c5f934585865f7c090f1c9ff1f540 SHA1: b130675b89061c864f4b70f73ab9c32a077db0ae SHA256: ce0bf042255e4a978119f7453f0256b59f4b95e67ff3c2452a6ddc7910c2eed1 SHA512: 2637aeda9b91132bb55e6470c2161a1712e3a276f9ead7a0d1d54e582a9e338b1fb5e29584dacf228fa7ab219bdb8cd83bf0b94103b1ba50d112d9b3f3d10260 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13304 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-webserver_1.0.0~beta.4-1_amd64.deb Size: 2517976 MD5sum: 4ffc1b6f728a1a7a45ae2074f581ac5b SHA1: 3ad6d56f8aeb03dadf8f2f5e1949529d346b3310 SHA256: 136a3833c211c2b575dcf21c32a90bf436c8e06b8f821eb58528b5f25cd565ad SHA512: 05acb425f5ed343f23183a2d1b53feb6c1d374751b9b7b1cc5feadea36a0444832f335f4b7865c32640116f200ff62824aa66a5b0a8a521e7f654f2a64bdcfde 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12498 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-webserver_1.0.0~beta.4-1_arm64.deb Size: 2351212 MD5sum: 42b745f6aeb6b917632dcb27ed55b4e3 SHA1: 29daa4224a17e3ee95bcd2d83951d494e4f194a1 SHA256: ba91121605140e5e0c48181369a775ce62894608cdac7170bd7c5a84e2579155 SHA512: 6ebe3a5e17b90a74fe0ecfda7b187fa637111c49639bdcf34e160592ca84994c7437f0d112539866a9dbdaf4bd1f36ae643144687c72a0cc336e20a3b2a5c8b8 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10193 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-webserver_1.0.0~beta.4-1_armel.deb Size: 2147388 MD5sum: feb4a1c4c5558ed4de23d1f9a5aba4d9 SHA1: 1ffbc02f1d8aece10d180f6438bb39e56974e46d SHA256: 10ba4ef29828309823bec3dceee22eb1c92f08e20a540d9d7756faf796b939fd SHA512: 1844b9de23638cffe7e4b48dc45baeb07292c6ad4b53b338516595d5e003671f09635c240f10ff6e1a9e6a85505d710c5aefbe44f93dee0342f5427d75fcc723 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10061 Depends: zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh-plugin-webserver_1.0.0~beta.4-1_armhf.deb Size: 2131352 MD5sum: 6025f78cb275eb9c7d74c5c7f209251d SHA1: 0dff9076b942e9cfc6ffdefee249170a1e4fad6d SHA256: f8ff875b6fd255babe97ba0063df8e034d7b6c91b43535146f733f8614857666 SHA512: 280bd555ca8798890f1f8ed2ede35c4b3f1471baa8581dd5d317ba4d6396fa0baadc8224898e9c079e8ac891fdf5b4ba5d03eedc2dbc0f76fafd2f5b488e3a23 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1), zenohd (=1.0.0~beta.4-1), zenoh-plugin-rest (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh_1.0.0~beta.4-1_amd64.deb Size: 17344 MD5sum: daba84bc355dc20ce02e215b9c33ca1a SHA1: 76313ff2362fe15bcb2b11a217b19457451572e1 SHA256: c479e7041feccfeb71d394659ad28f8219ddb9201453d397c32a2d5dd749571e SHA512: 4386e8f9aaaa35bf8280def8656294fda86c08884cd6db45c4165230cd776cda2ad109deab298850c875be8cafaabd7443f764b0ddaf1452a43512f947c77d9c Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1), zenoh-plugin-rest (=1.0.0~beta.4-1), zenohd (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh_1.0.0~beta.4-1_arm64.deb Size: 17344 MD5sum: 85f86669ecd96eade97e259e032ca2eb SHA1: c10a2d9a0646e2e2d8fb75f90df52a8030838439 SHA256: 79e03fc601d954e24d2c0ebe84a7f182b0921780e97f02d9b70d89846d819965 SHA512: 9e1aa4e8248f55028b849f0d97210b2ea2714194c076fada64805a2f25cce30ade4471d6680cdb4929ed6c8a9a003e5657a39a5e4408dcdab6a5d35a0c98a1cb Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~beta.4-1), zenohd (=1.0.0~beta.4-1), zenoh-plugin-rest (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh_1.0.0~beta.4-1_armel.deb Size: 17344 MD5sum: a463bd2af1d460e68bde89b71d2cb930 SHA1: ac69e03b8f97a6296c9db1c3a3694ec5818b19af SHA256: ba96574979ded85cdcba5abeee0e16b8f7841cd0e5de9e58a4907477f42796d2 SHA512: 46dd0e69dcd767e706037e7dd344fc0dbf9311fdb8ba861e266f4dad825b7df2b8f884fad6d6f13ca367d311a3786c4a08a072facbfd6100d4a2e0cca74e2395 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.0~beta.4-1), zenohd (=1.0.0~beta.4-1), zenoh-plugin-storage-manager (=1.0.0~beta.4-1) Filename: ./1.0.0-beta.4/zenoh_1.0.0~beta.4-1_armhf.deb Size: 17344 MD5sum: de59f95e8e866e2aec5d0a43f0a4d98b SHA1: ded3406cfe43238a95cde1630ebf7d924aa0903c SHA256: 66d4a2148e038c442ebb04477ebdc0ffc7c26ff5d3e2051958e0cd4b7135fd2e SHA512: c1fdae7c736577206f505f4a4046c1e175a05d0790575310547e4716bb714a88c7925e9e73ee5edf48a82bd7c10f200950d8101fd947e015f6b2f827db888890 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18015 Depends: libc6 (>= 2.29) Filename: ./1.0.0-beta.4/zenohd_1.0.0~beta.4-1_amd64.deb Size: 4416392 MD5sum: c3534e049f3686a466af52f07048f02d SHA1: ca02ff47ae607a95c80a909b4a358c11dd99de3d SHA256: 93a2a3eea11401f5a264399f5a9c502765f23ff6cb7b5498da68016e33251944 SHA512: 53f7787bd7ee262218e323aa29682b3a1a93c826b6f0503764133c5ed68dd6b3bc10cb2bbfb9a2a4d3ec5201f8e22048295a7fe9503ff84d2ae02c1e28ccb2eb Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16163 Depends: Filename: ./1.0.0-beta.4/zenohd_1.0.0~beta.4-1_arm64.deb Size: 3972524 MD5sum: 72822dfc5fd4df23736e5c4dd4691d9e SHA1: c189c7b3b2502eb4159050f9a95c3e3a632b3754 SHA256: c4e84c99696e3174732e21be7cfb86c1ceff26dad3d199b6e280ef510ccbd663 SHA512: d3abfabca8a5c65fc9e73ec2af5ef14d43c17ebac943684f1d5f4cf9850911b51c3917f2a869c8e2d349ebbc67e32cb1ad6fd7c280a46f4bc3bd06a9e62988f5 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17511 Depends: Filename: ./1.0.0-beta.4/zenohd_1.0.0~beta.4-1_armel.deb Size: 4318688 MD5sum: 2b99c626200a3ac3bd40edf4fd471f0f SHA1: fc43419e5844ed28bbd7c3229c75b126efd84343 SHA256: 12a8d958ab9ba64e2940734aa8139f8fb5e090507ad5107950b095e71f792895 SHA512: 14ddcdd36aa8893c8b3d64b85bc6f94a173836c511e9212fd7fa6be555d4bbc170397c78b7cb1a067211daf32c0d97cd70dcfcccf81f905d45a51a23d62478d7 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~beta.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17295 Depends: Filename: ./1.0.0-beta.4/zenohd_1.0.0~beta.4-1_armhf.deb Size: 4375220 MD5sum: 6ae1651d3b25c1dd4eb2dd34ef58672f SHA1: f54fdd9086120ff78a08ddc8632de5e0d21373ac SHA256: 64497c1ce29d9e418a71afd089cee3a5f9dbc3d7055898631e6d19358e27d5f2 SHA512: 35496924c7d337b759fe30d2f03d7636dc2ff03d9e1a8b58ab82ce93530574620b9e8114ec35b947d8f6837f026cafbc473609da68ecc2751fb1cd3dea622c68 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20835 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-filesystem_1.0.0~rc.1-1_amd64.deb Size: 4601328 MD5sum: ce259dd525833061740dbfac47d0542b SHA1: 0b2f7d1b55f88e1a9e050f60e115486b9696f801 SHA256: fe88e73a87ae487fd38d4fa26126f93714ae4fa651e7d6b8ab2d38ee6d64c844 SHA512: e4972f0f79544967f9e9b9c93f7fa3e9b90f6c36de350ba97a03f69e5fb21a3807c32438fce4a72e75d20a022a665385a6658769652522886ac79acb84f33940 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18956 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-filesystem_1.0.0~rc.1-1_arm64.deb Size: 4140088 MD5sum: b6045c733000ea636f29a6b922569731 SHA1: 4d05854aae63599232161c7abe8c1e089682ce00 SHA256: ad8846c4e9b5e67f04e345a977af5a4690464ad3fcbf9403ddea2b2ea6ecb23e SHA512: e6ad306518256bfbbf36b2567542994066c173cf8840f6147c12c1e86e699cb40c8c148e1e37a4298cceabac1b128735c9618a45b65a66f3afc3a1707b9dab21 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16513 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-filesystem_1.0.0~rc.1-1_armel.deb Size: 3911172 MD5sum: d3e5e7c418679567aee12341887ae70f SHA1: f99b41ff94a086c6815a793b2a10b9e4172ce0d5 SHA256: 88c63522baeff81bdb1a8c0cb5bb21999f34b339a66ba2a4773a4a95ebbe0827 SHA512: 0dc81a5008890eeea0b9d9a43f92d522bf95be019212f453d519261e27dec5d1312b867101fefe1fc897fcb9cfc453e7cda22f26fa8fecd8e6895d09303ed7fb 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14628 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-filesystem_1.0.0~rc.1-1_armhf.deb Size: 4009568 MD5sum: 11727ebed77ebe17838c77048a60fd2b SHA1: 5e804c266d124bcca643a2d991f4cecd52fe8d38 SHA256: 8c3e2f14fd3d2545c015d9a218ba0caac5f918a34eb79120a7b029de926b9d75 SHA512: 62348926e49477c812eee9288163bebd12595d34bc66249c249fbcfeb4d684c7733736126298b3d69bb9cef85ef4fa05404ac08dd2b1f2d450bbd6e0fdfaceec 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15711 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-influxdb-v1_1.0.0~rc.1-1_amd64.deb Size: 3126808 MD5sum: 4cd1fa290b50e9e55ea76d813f4e88e6 SHA1: d0023ca5ac6d92225a958f8854e466956d252aa8 SHA256: 0891f87008e21c5f026b210c1a3de9260a0bdf5744538116d12a119fcb297d53 SHA512: a79adadd694e361003b5ec651f53e4a27f5f38e29384f22864338a4984f783cc024f2fda5719a97d641c7304b390405200efad7d0a9c971b961ed256da1102b8 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14032 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-influxdb-v1_1.0.0~rc.1-1_arm64.deb Size: 2813108 MD5sum: 224e45c369e30b2cb193fc3601489275 SHA1: 0ddff42c16b1f9d7096944857e30473034a7981b SHA256: 11302fb02aaa0c7192c9d6aecaeb83431bc8e52f7962017af0f74abf17848d0f SHA512: 9f52aaa08752ed80ac4a92dc5b70a948523270373c364cbd980d27e11242bce39bf963f5c642243ead88eb0f5b83009500accf19b0608b117f3b41be7b32a638 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11805 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-influxdb-v1_1.0.0~rc.1-1_armel.deb Size: 2552220 MD5sum: 5ef9d64f349434f101de4e9a9220a5fc SHA1: 2dc5ba1d9c88b228861ab6a295b378c055e948e3 SHA256: d022312935b13bdbcec4ddb683aac4682a460976eda6f7263307341e22579f36 SHA512: ee6eae42c3f7faf9e4480d498acb9241e008fff4ba7a7080546b2e3f5fc1f145de60eade8e83e9a95ec44b7995c5887f2ca0cccc617c36c82db59f1d44b3ecaf 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11678 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-influxdb-v1_1.0.0~rc.1-1_armhf.deb Size: 2542728 MD5sum: 0bced463231e9261491beda27622ffd4 SHA1: 0befa8fbccff2948eef6e034a5c5a6daada7017c SHA256: f1c1dccd4e6b02922fe4b7ea32a3e76857770af7e3ae20ae7aa3108dfefae4fd SHA512: 3ecdbb25d44e6c2d73745e314ca2dea37ac15312967a187b92586e82f320ada6e398994258bbc6ec4c8465902f5ffd79759d0614812a68452335d53d710e3ff8 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17298 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-influxdb-v2_1.0.0~rc.1-1_amd64.deb Size: 3801932 MD5sum: d868270a1c9be748ceb1e87f65b23b50 SHA1: 9f7c9de7b70abb8d1289f1a31e3c9cef5bed47f9 SHA256: 7790420ded8d8b267dbab566acc24d7113fdb93698f8f8e5eed2a1e20cd2dcd6 SHA512: 726ca9cefc49b7692710d429f02bae80bfcfb843059bed66c52c9398d8fad8334fea930eb80477b74f0656afaf11fd21b993389f651dffff5af56477e7c181a6 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16283 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-influxdb-v2_1.0.0~rc.1-1_arm64.deb Size: 3488940 MD5sum: 64840f46b2013800739ec5fc6686a4aa SHA1: 1695507e431d00d196fcf971dafdcd30781fa83b SHA256: 396cb15f6f3aa9ba9f59c39af6b1eb6d1473b2ec1f0d29c923e9aa9bd2c7997b SHA512: 2012d493b3ff0d1aacf5d3e3b3005646cc252645d88a6b94c731773ad0dd85190bd90ceeb56d395a06b895e83e63fef92e12944df15ef1ff255c5e19330a6877 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15591 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-influxdb-v2_1.0.0~rc.1-1_armel.deb Size: 3467632 MD5sum: 6fc42af2f6fdeaa262974850267e16f9 SHA1: 4485809bf08f5f0183118886c906ba3c508527bf SHA256: 3fff06abf2d565f78965983d876c42a2ca5f30b639cd22bd0d42b8d5a9cd8f9d SHA512: c058b6e4e81d624f18416f6a9700981972a4baa72e061a76b805dbbc7856f0f840699ad18591bf797be21c3510298d60ed8a492a924f9150cb0ad34ed13af443 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15489 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-influxdb-v2_1.0.0~rc.1-1_armhf.deb Size: 3509420 MD5sum: db5185a743bb74341ae9565dafd03839 SHA1: 17dfa81a9ef0c20ef689ba025d4df0ba4f940a21 SHA256: 0d7f1287c1b52571e11836efd418061743c37b216a2dbfb72311a9bbd331db52 SHA512: 60c23ecb4eec5aa71ff400f1b326286fc7f02bbf88fc24c1dd0263e97b7b9e759579a68735d2e4a8aa48bd01fdf3e1778aa7e13d94676ec789245cb87609468f 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19383 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-rocksdb_1.0.0~rc.1-1_amd64.deb Size: 4330632 MD5sum: db727a0ef76a290b537b94752ecf650d SHA1: 5875b929c9c6a8becf87e1eac230654c85c87b26 SHA256: 0e53e854bdfd85f17779112c8d1b061b5a2e510c9925ba9cafc642e159e991f1 SHA512: e3e9f7b3cb1960abf2c12ce296a704f09980384f2b412dfed8153d7895b6adff5b59f7225dc0b515d62f69aa6b62c6c97e56a4e269cb494e0b93e584993d47b4 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17488 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-rocksdb_1.0.0~rc.1-1_arm64.deb Size: 3886776 MD5sum: 9562920cd9afac57978c97f2b487eb70 SHA1: 77186a638212e7cce180efe579d58f387b4e606d SHA256: 9839e8a391e3b0fb65d630d83cd95b9f320751a7147eefd9f4aa877ec3866e55 SHA512: f869fe6c8ace4df4a9d75dbdd513ed93f5705a5cc7493fc476262c0ff5bd01b08ee96080904060957343e9f7d2052b497c2a69ee9e7145cfc1c6680f15ee8ea3 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15303 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-rocksdb_1.0.0~rc.1-1_armel.deb Size: 3700204 MD5sum: 15455cbde6f01d8292e94826ffdcd57f SHA1: b9594a9fd040db7309581d7702eb8dfba801ae0c SHA256: 0bd935d06489b76b65d624c8856ad4aaaa7c1b630820ab80a20457621b2255a6 SHA512: 1c36e44722fb1e4da3664f103ae89b3639ef25dfa8e6430ee771dab2b86a89a6a89f78c18d7626e43306628c0cc2b70d80af7ed637613886565775c7295ef0c2 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13400 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-rocksdb_1.0.0~rc.1-1_armhf.deb Size: 3797820 MD5sum: 4c7422accff16ae13e8edfa9b1a71264 SHA1: f32586e057b3747e50f749898ebb907ec5eb58b1 SHA256: 2a95ee2775e80028fa26a06b9a9a553a295fab34c8b105b89f7c276cedb29ce8 SHA512: e6e652c6354f63a78c24cd514ab6200e535616d0a21f3e36b9c705cb28a8d37395cca86697adf05b3de68220aa2fdb55dc5be4ce6f587dea4336e0693c4c0ea9 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27249 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-s3_1.0.0~rc.1-1_amd64.deb Size: 5511264 MD5sum: 88d1b9aa0d72c0c86532d99513f204d3 SHA1: c0e655b3c92dd4401446e17eb2ceebca728c8b15 SHA256: 32485793960cfabc9a7b9f4ea1d483ee197c3419db57dfccdf686f5ce683421c SHA512: 2a2e8d177da63cb7afddd4e4aafb40fe57e2f41b905267b0160fe01d4e7ab347e44caaf64162bde16dedb65c6cd409e8b0f4c8fb3504c40c6a0be6ecbb5ce26f 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26490 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-s3_1.0.0~rc.1-1_arm64.deb Size: 5228124 MD5sum: 7a3bc4ae7b52b7cb54adb65a259ec62e SHA1: cdc1b4c9170c58ecd962b6285e712d8a83337b5d SHA256: 27a92bc0417af9c0a1df9d05e5fd60a53a268c9ea18aab153b8240e81770cd5c SHA512: 1ba5ec0b6c3001df7433cd7d8ed5e8a4668249839bfb59664a8464a4b485828b9f9e9a1c6ab72aa8c137a1d26b086834f91618482774b1cb4c27f759e8448571 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25153 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-s3_1.0.0~rc.1-1_armel.deb Size: 5087148 MD5sum: 40239dccb40d7a30e4c11871bc47bec2 SHA1: 81dafabea85b9ffdb7fb30580bd6d6c455234a68 SHA256: 1fe29feebd1390cac2433226e415701dc73fddb3ccedb39b8532f1015bd212f5 SHA512: 1a2ab5b3895cec689f13fc1762cc8c42b3f696103501be04d74fc4f7586c75885566811278e6f636f81fd067b08bc459bc274d17df53d01f0da7af06511355fa 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24926 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-backend-s3_1.0.0~rc.1-1_armhf.deb Size: 5136568 MD5sum: e30bc098dfb4164d33332788131eb4c8 SHA1: 6a9fcf005c1d3dd4729821bd169717e303d1213b SHA256: 2d1a58c53b6f342f9110affbce4997d13221306c73dda5770f7cb38a92ff12a2 SHA512: ac29643bc1f8013198ef100916a12d76dc8101aba4d34ba0bdcf930c56e63fa694b93c349a4962291f721c8dbd4ae6c892b05e2a9f69de0050dc11f7914517b9 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20570 Depends: libc6 (>= 2.29) Filename: ./1.0.0-rc.1/zenoh-bridge-dds_1.0.0~rc.1-1_amd64.deb Size: 5275956 MD5sum: 45c1fab6aaace0029f76bbe56938edc3 SHA1: 76cc6da4732c1ff3ef9de4b258ab042bf2e4a21b SHA256: cdb77500dc5080bcec090c8dfad8e8e79ea65ac7585edbca05742e2c23fead65 SHA512: 478f618f30998a17ffe8cdc1eb9ed894be9db2bff02ef230a9844e3a5ddc51d11e20d2026ae93f6612be2766ecc2f9b1dc3f05e3f0e5df504964951ad1d1f463 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18801 Depends: Filename: ./1.0.0-rc.1/zenoh-bridge-dds_1.0.0~rc.1-1_arm64.deb Size: 4766652 MD5sum: ceb16a36c364c38dd6ef75621f0a2e59 SHA1: fd57d3711e780177ffd8a4dc32260cd0d873b4ad SHA256: fc87819f322afae1415827560f019bec418f3696ff997112d2ca45889e7dd5ef SHA512: 8d206398cc30d4f76b23fe5d58ea70100815cb392ea720855515d42e0b89ababdc7fa83e6fb35ae8003035feff03da1f40acc336df09590e2a0218278a37f628 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19935 Depends: Filename: ./1.0.0-rc.1/zenoh-bridge-dds_1.0.0~rc.1-1_armel.deb Size: 5028096 MD5sum: 02d10e59fc124b674b5b58f5f2ca8088 SHA1: 35cca425a1266d60980f0c866ce6c7f747f2977f SHA256: cfb4592f9b57cbe7327ca0ee8557552a036e6e5d8102300ab178d3c40efda036 SHA512: 19fef91fb043c7ceacd3fe37280e1b211d58906abcb87f0d28933e1b668e503979812faa0f6d1084f8ee576a8914a67808f73094cb131fb904e69ea27c21cf74 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19423 Depends: Filename: ./1.0.0-rc.1/zenoh-bridge-dds_1.0.0~rc.1-1_armhf.deb Size: 5082212 MD5sum: 98691478e2235cba7e90b415f4b84e18 SHA1: dfc68578c029490c86e34c0d2e693e51fe8a8cb4 SHA256: 3aa04e44fe1c76cacf88096913cb245e6719396218b3b02e1f62c0b747798850 SHA512: 0f36bc00a32dcfd65f2cb2795db532b15feafcfba63149ff6bb10534b536cbfc489d984c8437a13c0243a7e1912c29eba13dd520faac11c8de3f55fc8c803bfb 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20501 Depends: libc6 (>= 2.29) Filename: ./1.0.0-rc.1/zenoh-bridge-mqtt_1.0.0~rc.1-1_amd64.deb Size: 4945032 MD5sum: c0a841f729261121c8020f338c64de53 SHA1: e79a0e1201cdcd6e2f60c2c8e1dabf31afc63267 SHA256: feacf29d35ae85bc245f94e27f3c129b69c094962670d50a2d6d844e80325d70 SHA512: 4fdb45d98e5b07f64a69cf01868fdde4408bae1bb98410e25f6874b75123b1449e6e664ea0960e8756ae58ffdd06381488350a1d76118c1d516b514845eb78d8 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18724 Depends: Filename: ./1.0.0-rc.1/zenoh-bridge-mqtt_1.0.0~rc.1-1_arm64.deb Size: 4471484 MD5sum: e04a40467e317790ac32c042a0a0286a SHA1: 34d244cc7fec1c25441a2bced6ae9eb1eb579e22 SHA256: fe878279baf056bc2286ff5d0454ccbdc3993f9cd0d574fc894cbc4125991c5a SHA512: d8a0f125c9930ade5acb295caa5e496f762ec61699bf63e73d937cbc7d2670fca4279c7f72467853aaf5196ba28d5870aa0ba574ed27c2c3bca5e5dc948ebf8e 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20028 Depends: Filename: ./1.0.0-rc.1/zenoh-bridge-mqtt_1.0.0~rc.1-1_armel.deb Size: 4754440 MD5sum: eb79e2b7bea64231155a75e543cc35f3 SHA1: 94e9bec4c75dee566048b86146978b9094418aef SHA256: 8428886673d131feb66b2502910ac1ac54ca8e3effeca5207cb5f574b32a731e SHA512: da48507fc855fa8acb14efd30e6d1556f6787abc2613ab5e143fd5e8458e9dc2646925d898076ecf7cd04a0cc8e7446af55419995b26cadabc8446671fef4f4b 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19755 Depends: Filename: ./1.0.0-rc.1/zenoh-bridge-mqtt_1.0.0~rc.1-1_armhf.deb Size: 4787880 MD5sum: ff2442c78b237777e6c734b1f8c7be50 SHA1: 14e9b29ef0bbb811382e6562ec648400a6a6408c SHA256: 8158f942a85a46685d2310a203c89263f7f20c574e89ff459eceefa229bad465 SHA512: 8990aa1027db881f3715434650813a9e29f142a737b91c459c6b274d8d6a16712335b6921784cdbd09bf6e2402f6ab721ec6a72090b9c806645aa57c76205b64 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-ros2dds Architecture: amd64 Version: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21127 Depends: libc6 (>= 2.29) Filename: ./1.0.0-rc.1/zenoh-bridge-ros2dds_1.0.0~rc.1-1_amd64.deb Size: 5371044 MD5sum: fecc1100c74f0b46c97d8c8f3380483e SHA1: ac00e76ebc7b4df5e481bdb30f8ab067b6f505dc SHA256: be5441f720dcd055b14dfd2f7a4ed9a7480a2fa301ee2c5cc0409daf54017bdd SHA512: 04edcbdae6b21fd4ae1a97fde6c4115fc9548850d181c768ad3c77f39b62f572820f2c4d66fcca70973498785a924c744a479ef50d27eee995e37beba057bb48 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19328 Depends: Filename: ./1.0.0-rc.1/zenoh-bridge-ros2dds_1.0.0~rc.1-1_arm64.deb Size: 4873352 MD5sum: 632080adb6c3914916b913ae4977fd9f SHA1: 05331b2a59b9eb47e6b3ed959b5514969e8a1184 SHA256: 52aa64edb568974f18ff78a30ba3a07248510fe8676c9ca56ca7c9233dae755c SHA512: 14b41beb6f67495f4943ead2029ad0e113e2092a9b72f902589c50d2647fbb32c1daf10046d5efcf5a5f6866608e7c66a5beb78958bf6f44fd8804aceb78e870 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20465 Depends: Filename: ./1.0.0-rc.1/zenoh-bridge-ros2dds_1.0.0~rc.1-1_armel.deb Size: 5138876 MD5sum: d59aa616b581119749c38f710fed7806 SHA1: 8de381c857813b76c5a7481cd5eba248605261b0 SHA256: 506d9313e7751ec66ef5c9a637249319f0120bf534af914ea2ae1adfa5704955 SHA512: 9944ddfbb8c74d004d8be7330210f1c4acfdcb1095fdd24b2fae45a7ecd135f7b1638de0d52625e0672858995cbe5badfc51d41cf2cfd44aa11b6cf4f20de889 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19956 Depends: Filename: ./1.0.0-rc.1/zenoh-bridge-ros2dds_1.0.0~rc.1-1_armhf.deb Size: 5193636 MD5sum: 81d4713b7a95aba1f8d9ac6a99ad9c32 SHA1: 6de1a0b69cfb79f13c71ffb4bce26b5e6857616b SHA256: 3994383fe8a1ceae4aeef4063aa1190c051c34829f26a5eeb85561a4b5b1813b SHA512: 4edf470bc35054fa3c2d00139c8caf1bc3e938c03f66b00c8c1efdab9765062dea0c6b00b2f4681f10aca1ae16c979705d55490eda9e1807b9fe5774d4b562bc 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12754 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-dds_1.0.0~rc.1-1_amd64.deb Size: 2568320 MD5sum: 1d978b97cc41d195c0d18e30a7db1f1e SHA1: 35c44858f110aaf95619736358db42ab483ce7b9 SHA256: e7dd23e90f9291d61a0f576d3b71bd90f5136a09aad99e5168bff08474edda96 SHA512: 5bf816d9fca06e29bbb767cfbc7e80496b0c6d090414c6b4d1593e4cf973226b9651aecb914ed0f114bbb7c5e70935d8e597046cec0413cc0f3f5c2e3cf48a59 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11569 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-dds_1.0.0~rc.1-1_arm64.deb Size: 2336356 MD5sum: b2547963fb585e21c49435a0cf9c46be SHA1: bfd6dfc54bc12628b56de2011396c9e3b30ae30d SHA256: cbb13fc58d1b667e6b20cce7c17af3832ec2ff20615a45c9eafbf89862ec9ce3 SHA512: 5d1da6a3dec387dd0bf67665e1db4f9c6622b796b285708371aa12994ae9b7b10cda46b3af0a08d5f59ca45a6733e6b4a8e03a0638ce34a8b2b007dc2b890aa1 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9586 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-dds_1.0.0~rc.1-1_armel.deb Size: 2182184 MD5sum: df26a808b623a601293c304df0b8bb63 SHA1: c6cad11438987d6ff2ad4bc21081fa1e4f7c7f0f SHA256: 2575edd4a2e4df3001edba8d94c0edde6c1cbae05233ef3a16c1083cd3388f9f SHA512: 8f1876d1c7d078c1ddd7451ba39d294a350edbe4e81702a8c59a1927e15e1c4a23a3d6444784d8a534d4a5a876f99b107cca20f613c8ff4156397558f7e03574 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9206 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-dds_1.0.0~rc.1-1_armhf.deb Size: 2189076 MD5sum: 672821c3bc83d04da51a5f8eae904c1d SHA1: 3154f652381ab180c77372165aa0ca9f258c03e1 SHA256: f3e35c6372013a36450afbc75adc0ff59504baede27d8324667facf9a1d70b1c SHA512: 527f02285767f42d21266c28944287cb0bfc5a10e4715a518a71e5638e159b4c95a6c4861e0607dceaea23510f43e114a41095ef8646b9edc9892a78edeb6c67 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14039 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-mqtt_1.0.0~rc.1-1_amd64.deb Size: 2873640 MD5sum: 7beb5787f9cee317ffe57429dac75caa SHA1: 64691bb35583de902dfa23e08f04165b0d5b1ac8 SHA256: 566f486fc11c19b4606488ee539ef21afdfebdda58b8fd8206334c8db17369db SHA512: 305595674273ceaeff117575d287159270d68b38d0a130f76cae3e6132d07734df89da9424214e144174221aadfc6c09b55a5bde38d5657d6d5373c4b44947cd 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12763 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-mqtt_1.0.0~rc.1-1_arm64.deb Size: 2568724 MD5sum: ca96d30849f6530aaebcc6adce51486d SHA1: 38becdb8efa840e78b270385f8da9e2a39e8ea26 SHA256: b77e63bb3233c363570c275908ec2540476c3851d9641e36772b5e905b7af18e SHA512: bfa6d5bd387a39df256fbf4ba53a6db69532d078ee18fc9adb440ed60c4d989ce9bb52e010214a42d1be5055ad9696114bf1a63deddc0a5178e745a2921a6363 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12759 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-mqtt_1.0.0~rc.1-1_armel.deb Size: 2634872 MD5sum: 8b0b9d31afb52684c35a2be0f4b9c8c4 SHA1: 13a1dc61cd567461257e094808e3c96da2eb5e83 SHA256: 04d55f6fc6a664235da9fccb6f56e6c704907443f792d4b03e232ddd2aedaf9c SHA512: 2a8a9a961d03c84a23edd3bc0e36df7c4a2d3b51a72cb71270030847f81d5496c6997dd240c524ce3eb7dcf71fb39bc665d1b8f3a751ba9744ae8cb5ec91da1c 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12679 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-mqtt_1.0.0~rc.1-1_armhf.deb Size: 2678120 MD5sum: ed364c65e61f8de3b8dc41e7adb3181f SHA1: 71314d6e56747508cd868add0d85dbbcd5b513d8 SHA256: dd5a64de83925b5f8aaf3c79bf8a9ee074979bd14a7b3e0d2275458fe6b0b515 SHA512: 2c3e5bb1cdc1558526b0c88c86550157b764c16a6d00aff46d3ffa5c573e73caf051390c8bb3d16afd2ec223a4e73051013628627cfe0cf21d97821f44de4533 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-rest Architecture: amd64 Version: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10854 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-rest_1.0.0~rc.1-1_amd64.deb Size: 2087116 MD5sum: ed2c2cda860b60cd28654a9cbd9c24ea SHA1: d664af37dcf914831b9a9b4cda7aa3de48670730 SHA256: 6ae887aba5e05ffdc2d8c4791c871cbbcedecf55d832a517977f5065db7bfc7f SHA512: 8e2ed3e0da2f2ee791a6dd0cc5bc055fcc9afff5fb9ed1e7b2de40fc2dc857790f7e0861058bc4b00d88ced128046f75d141348fa7bfe0e43b894e9f40227050 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9835 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-rest_1.0.0~rc.1-1_arm64.deb Size: 1912408 MD5sum: 76e90b05cbdc9f429a0ab9632c9bfda7 SHA1: 4f8e83c3268590f06a7b1a0542bcf1c556c2f678 SHA256: f5c83525095c255962faea4d74b1e0d584423660781f670e9b95380960fcae66 SHA512: 6c00b7adf43792a5e617df911e77be9a0419ed8a61f68da9a070508c0989e2dd4179b6afc7e87096d4e19f893ab83f7f05424084a75f7f2f3843e2e85d0db558 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7981 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-rest_1.0.0~rc.1-1_armel.deb Size: 1779996 MD5sum: 4b920e58afbfc9b4154c6947d9df9207 SHA1: 5b5fa94c5718dc2cc8e6394a9e124aa0cd3c7a1a SHA256: 25a6daf5eeba0fadbc3deb2e5d5feae234ed1304a26331b0d2856688e9957eb4 SHA512: 1ef8d84d26c35e37a4cbe456c2592ec75989247f592005cade17c72e7dfdc466237258d31707137874b17674aa2154dbeb655082fdb2bafa7759901e66970ecb 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7887 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-rest_1.0.0~rc.1-1_armhf.deb Size: 1770092 MD5sum: e28ce2c4da8d71b6e319fb7b68545698 SHA1: 809e4583bfca3b024a84d06fa206a8a5901bd1f9 SHA256: f1869fff4cb186912093a9570b00aca1840b6124f7d5f34058e3b85d60ea16ae SHA512: 0a06d42b1ee65e86b788018b8701bb25206799c6d1cf4a283fc9d5fbd8fc1758b4aca296dc8efd32fc2b6bae5a4000d329d9fe84ed8dd8e6c4d45e3bfd7aae0e 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-ros2dds Architecture: amd64 Version: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13291 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-ros2dds_1.0.0~rc.1-1_amd64.deb Size: 2661656 MD5sum: 4a431accc302b5a90b34284c7169d18c SHA1: 9239ddfb42679805d8043bcc07154344c63a3fb5 SHA256: 631b8bc9959727a23a4fdfff81226edc0c8b35fab92a55a998741ed1d4ae5bd0 SHA512: d7fd9cc414e1b981b9c9568ddd17f7ca590fbc95c97c3045c22127740cbf4f9d1f8fd4a6d8197a223666c21ce83d637a1dd5b0d1011e9f46437ec3387a5cd609 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12056 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-ros2dds_1.0.0~rc.1-1_arm64.deb Size: 2427336 MD5sum: c4bda9652afc5db3f6d931e3500947a1 SHA1: aa6d30b6436f62939ffebcad9f81153e3ac41998 SHA256: e072aa9285b09a2791d48ce56f7391cc297cd825090a7b35dc029c85b61ea4c0 SHA512: 323a0fee335250244b4f420f708586167c1f3f392509715fb4b122410cebdbfe694746949b0ede52f09a41bc7f42aa9f9201940128247bdc14b3ddd1ef709cb8 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10097 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-ros2dds_1.0.0~rc.1-1_armel.deb Size: 2284456 MD5sum: 9ed1b7fc870145c16715f3fa857c519d SHA1: c86f26935164ae2e4db22c1915a65276d6d0ffbe SHA256: 493ad0e50273e659fbf5622fd247d113ada3993022e52e8804c69a75e8522520 SHA512: e14ab7150626d2d68c7df2b8bd7cb55041fd9b8b60f02516dd6496f557f644f1fd04f3d6662e3516d5c64f07acd8c5279f0a61347349e2d65063049b085ee830 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9719 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-ros2dds_1.0.0~rc.1-1_armhf.deb Size: 2292056 MD5sum: bf5540c2f68d0447417c19803d9e91b6 SHA1: db8fee1c2ad1e1e7f873fb0a1561a452fe62943d SHA256: 02e22d741b41be8c113e94e972ea2d4e6851544b811bb3104066e35c53dc4c7d SHA512: ce0c4a8e4f11bb63c7a63b17a0e8718d60a2c4009fa544aed391e9d00ffa364a2163d26c22ff1ac9a84bbceea8f355fb51faac36519f464a92638b9988b54c87 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10583 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-storage-manager_1.0.0~rc.1-1_amd64.deb Size: 1977092 MD5sum: 23c92cfea44530a61db010a9b73ea4b6 SHA1: 478daf2f85893c79d6c841cdd0377c9c6bf043bc SHA256: 2e21d030e574052b144f6103cc5fd3ffc81ccab691dbfa32244a0aa1691b8cbe SHA512: 3eb27dd05fa9d61f86296a87f92ad543d6305d5a46d0246f86d1c1cd427d45aad1e6e348b5a2f2a4f959d07ed5851669362cec3232c0cdecc95f0af6b1867890 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9547 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-storage-manager_1.0.0~rc.1-1_arm64.deb Size: 1803616 MD5sum: 5571fc3684fb81bcf2be00b9df71f55c SHA1: 2c8d3f4e461e0c5eb081bfdee044e34e31f43cfa SHA256: 481cd2cfcc384669edfe1f764b09f757823cacd25863d2532cf41be2f4bc8315 SHA512: c40078a972e2e2da545218bb3cd40e5c9101df56de32cec5320d42cd22e1cfb4b3076ac36d895b69e7383d576d36f754e17e07f736f446b059705a39e5d60f25 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7735 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-storage-manager_1.0.0~rc.1-1_armel.deb Size: 1696464 MD5sum: 82529e503a87584de500d6e900c8d809 SHA1: a4fefb27891afc7f76b4582048dab41c24aa17a8 SHA256: a99b17f60c9865deefb6f29c1dda3ace65bd254969f38e0c58a57975e9240b0b SHA512: 4f36a016828015111d4ac4399812edd0bd1e2915d4692927f8dfc761bf3bf4942505dde4f2f53e47349051762d519b0995a428b1b0f02ceeb90d270d2157f869 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7620 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-storage-manager_1.0.0~rc.1-1_armhf.deb Size: 1683496 MD5sum: c14a4beff6f1cbba28fc09edea7ad497 SHA1: 464ec2d8e295c66b5c4198d38979f6457bd0fb65 SHA256: 581c79fc34631412ee9e6b95322d8d28b3f7a0ebc0cfb2cde6c8a99afe7386d5 SHA512: 1bf177bd6f33ce915b74a7a0a6f84127c2083adbf76d276eb042e57e713d27b655d99ab2f95e52da93de8782ce904caf46cd9e706a83da4b3c47adb7c27558df 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13305 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-webserver_1.0.0~rc.1-1_amd64.deb Size: 2518768 MD5sum: ec7bad2db1a01f68e05085b87c74e7f1 SHA1: 39bd20470f76f86f4aa1990733a73b3ecb609188 SHA256: 128cced1f29cc1457f0b4a617509b9d3d08a0deefa722a7c53a3e06f3e21fa07 SHA512: ed247c8b3830cf65d4269a7831c4342113d4bc808c692b2c4426ffbb6a16f58e9e4bad0643be411cbf0b6440dd61ef71d994d9d6e1de1a0fb20568c35ca0f7d2 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12453 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-webserver_1.0.0~rc.1-1_arm64.deb Size: 2343744 MD5sum: e7913c0bca1e55311e84dff3ebb62eb1 SHA1: 2e954c55c94783a9b73560f1565bff6306d3baaf SHA256: 610f159af94ee735b2eecfa0fb1255a523d11988259b5eb7bfd0ab921ae35017 SHA512: e48531447e357d8a51be2503bf1216b670500d5c45dcc4b9d0ddcf0c3337f823089336028263df67211713653cfff182704ff55adbcbd9367ffabc7c0c817f91 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10194 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-webserver_1.0.0~rc.1-1_armel.deb Size: 2144200 MD5sum: 64ddf57fddf56985e2def3898847884f SHA1: ac41bfaa92ec67291c8cff463374295d782c4ea3 SHA256: 3af88b5594b54239ce1fca82c4f858f2a4ccdd2596fad0786c155102693aa99e SHA512: 04dc9c253b71be2ab331d3df57b02625e4afcefeac0b5b0cf23f30c389676eebb4d9a127e89fcf06cb3808c0de1be1f2af7af66c823e380bb62e733907a822b9 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10059 Depends: zenohd (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh-plugin-webserver_1.0.0~rc.1-1_armhf.deb Size: 2133140 MD5sum: a2ba8ac249678d290e783ab02efb26a9 SHA1: 9d490b7f8652b5d7ed17a7a4f7d5a50143e8041c SHA256: 31dbad083f1e7be8ddaca44cf605d65ba636fdf13fee7c52591fd789b9a014cc SHA512: e02628200beb65c681b09cdae436e770d87a710d49e912feb292141b7af926cdfec839d798de2ce668350cf2a9ebbab6eb967f19ac1f456f4b64f110e07ccf79 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1), zenohd (=1.0.0~rc.1-1), zenoh-plugin-rest (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh_1.0.0~rc.1-1_amd64.deb Size: 17344 MD5sum: 735db33f6a56ca83f1a43340dfe0c11a SHA1: 5abb98f75f9dd472f55f4e4bd4d0b23a2ddcae3d SHA256: 8df542eab214c563d476e2ea06e6714ee13faa59d4ef67ded495c16ba524187b SHA512: 4bc4e3f01a558f1d86c79212b8004764848d63d72b4f029a539b42c0867d63f81bb6ae6c94edd835a3f86d2642f244ad08c9ae6202f90a67fcf50962b65d2b6c Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.0~rc.1-1), zenohd (=1.0.0~rc.1-1), zenoh-plugin-storage-manager (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh_1.0.0~rc.1-1_arm64.deb Size: 17344 MD5sum: 7eda4a19ee5d39c8ec1242fce4e7f2cd SHA1: 1304998b08e994838fdfd124213020b5c678eac4 SHA256: 7dc52b1725692889f4a6a613489c57dd4e97efd5d349fff71783bd0aa6fda57d SHA512: 04d93ddfd5f489ca30a761b1a411a316d02adef337c82bfdeee1bfba3b492c5d0cbfaf1340425d32cafb7c18e4e100db4b55e2af2a7505264955fc6de403e6f2 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~rc.1-1), zenoh-plugin-storage-manager (=1.0.0~rc.1-1), zenoh-plugin-rest (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh_1.0.0~rc.1-1_armel.deb Size: 17336 MD5sum: 388b6799f8599db9a2a7e308c4dcd830 SHA1: 1c5ebbdddd89924a8764869f26d2bbe4ace2afdf SHA256: fa1cde7a563333e4c80e3ff43ed1e068b2ee1025edfe8058cf5e9d6db8e75686 SHA512: 7cb8899ccea1a1195985ee47764091629458cfb01a5d93c34ce1cad010dff9ac3a70eabbb71cf0208e7a8175d16d0cba7479dda7a9382ac64f7af906b0710e98 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.1-1), zenohd (=1.0.0~rc.1-1), zenoh-plugin-rest (=1.0.0~rc.1-1) Filename: ./1.0.0-rc.1/zenoh_1.0.0~rc.1-1_armhf.deb Size: 17344 MD5sum: 1e58fd015af87b9cb6289461122f6570 SHA1: 84735435511d00d3d1de96d0cf7bacd1ffbb9572 SHA256: c986d2b0d13204495601e3149f80b4996698fb0638b57ff7b161e680a8821b6f SHA512: 9e11f2500ee7309fa094051e1215103f645e162a018c336b184d26203a9c7535cc9fd6295ee3034f261adb6fe655f899b7c4c2fd05536112885b8b126d790d5a Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18020 Depends: libc6 (>= 2.29) Filename: ./1.0.0-rc.1/zenohd_1.0.0~rc.1-1_amd64.deb Size: 4416520 MD5sum: 18f69019410ae927903d9e7120fcb944 SHA1: bcc57770e0e35d4d256ae0ba6fda82b4408cf502 SHA256: 6f1ba4e8af91579175037fa987ccb3652067d71a727a73c96d7f37f58903be13 SHA512: 840d31113697d99d659d2d6272974c1a6720ba8be05bd77907e691cdfb03108757a089c26d8da1d17fda9ca3a8659b3656cc7b3cb739023430d480bf073f4131 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16164 Depends: Filename: ./1.0.0-rc.1/zenohd_1.0.0~rc.1-1_arm64.deb Size: 3978824 MD5sum: 7eae370ff08c076bad5772a7eee562ed SHA1: f52b981b03915a4cec95e79593dca9aee9742e31 SHA256: 0d5d3207864bb37a6a89d5e057cf1f238b83340df09309ef518f84bf49dbf2c1 SHA512: c41e339d24a993ae2a2aed8d9aeffa10c3c902d49f7e7c5a6f43f29935d4ad4145201fa4f22da0c6dea1e42dc3df30b4d3c63a55d595022ccd567362d936445a Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17518 Depends: Filename: ./1.0.0-rc.1/zenohd_1.0.0~rc.1-1_armel.deb Size: 4319700 MD5sum: cb1cdf46095afc746f8f8d44231670bc SHA1: 868c6fbd273a6224c26a715b67c0fe13ba54493b SHA256: ef4621c045cb6165025f5c9db23dd5f682c731a12f6433412bfb477d35ed88fa SHA512: ea98a25ea5879961efdb73a80d99e21093a1376334e624a59f709898cc828c6def2dff703717b64d7836390269cf4102e6d075eeb53ba88d9d59e81077595a7b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~rc.1-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17303 Depends: Filename: ./1.0.0-rc.1/zenohd_1.0.0~rc.1-1_armhf.deb Size: 4377064 MD5sum: b27f14607cb3162cfa12c73ca695ba74 SHA1: 05c98fd1aa435c5c3f643a2654b2fd5066c4925a SHA256: 47d3c218b85ffa343e7f99fa27d034aeb843238042e1f18c42706080d3789975 SHA512: 389335f5b48b5075680e68c9872a954c45f6e8ef404bd3db7938b4635ea0296a9247111e4ee789fa99c7a7c210210b9495c8b3f3560ae53e098e2af7432df580 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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/@/local/router` * get the volumes of the router (only memory by default): `curl 'http://localhost:8000/@/local/router/**/volumes/*'` * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): `curl 'http://localhost:8000/@/local/router/**/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/@/local/router/config/plugins/storage_manager/storages/mystore` * check it has been created: `curl 'http://localhost:8000/@/local/router/**/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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20835 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-filesystem_1.0.0~rc.2-1_amd64.deb Size: 4601392 MD5sum: 74b5ea705d6309ccd29a3fd1e2626ddc SHA1: 0e7b74313d4e1235b2f850b626de3f4af61f3f49 SHA256: a810b733ddb74884f39cc3b9e1a1e755968171b0a95b33efc823cda01cc8da5c SHA512: b526c7bb10e94180cc37ac2c315e99c1b6915d501eeaef90e51354d79b551be90de67271ae3f1aeb1e37645a8d4a92212d028bf3241be3de659ace5a2b014822 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18942 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-filesystem_1.0.0~rc.2-1_arm64.deb Size: 4139544 MD5sum: 977834d155bf137382c2dadab4ccf50f SHA1: 6819c3d3d2d79a744277204a14126b81266bfe45 SHA256: 030a0e4df45935bb1517357fc7efe18fcab98349f0f00ba722a3fae1f6eb951d SHA512: 3451a612baa75a7898ac761e0e1d35ab3fe5f1d4f02cd4f4365b8df49bf99ac62a491f4675831f6f302d6a389fc30c58867689b62860bed988453634db4ccc65 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16513 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-filesystem_1.0.0~rc.2-1_armel.deb Size: 3910432 MD5sum: 3cab0bf36dbe3c4bb142e863afe089ee SHA1: ada808d29e013f34e20f465e2b52f70a109d023c SHA256: c4d5fcc3d2a39322b1020d8b30c705a3f661e89c32ae7e089f4c6ffd301d4081 SHA512: d9f6534a99eb0e3f9192814d42729a5461861b67c3b8d8accd997aff4d1a9579f0f681072c812e24fe8c49a600ce365dd3695e9d5349ddc6e1169a78a7ef8889 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14628 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-filesystem_1.0.0~rc.2-1_armhf.deb Size: 4011924 MD5sum: 1050367133d46c4c4946924c68cac97e SHA1: 826ca067f5978a51c891df4ab82d56ba1f769dd3 SHA256: 3965c0b9e2f6d0b18f7503e42a0eefa27c25db543cd47f84fc875ad2883674f5 SHA512: 512f6ef7c7a912b3d98e9cec21f83a85f8082d3c70c2b0557457b6998a71d644fafc704100057d16cd938190d90973a0b3c09499c19a77385936c561345fe66a 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15711 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-influxdb-v1_1.0.0~rc.2-1_amd64.deb Size: 3129228 MD5sum: 3a32f3b06695a197dc4458e867b99845 SHA1: 5f30f2ee58a9f3d944278a5fed60cbcaa3034ced SHA256: 4b435f8844921532e132f07ce64f2a61f63effa0e51fceca7827f25f317dd394 SHA512: 7553751c7f4a836ca688b7d845552cefec3f4a8f29a044ed7f562e784b75824c4c4f4a0aede7a76ec13d66c277ef67478c595a237ec0372dfe286e399374151b 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14025 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-influxdb-v1_1.0.0~rc.2-1_arm64.deb Size: 2810516 MD5sum: 17bef0abcecb19f715f1d32d9a954f86 SHA1: 51d2f61fe910671ca2b15443b1b0ed677d7ae279 SHA256: 7279264af1552e698d65465f5fdaa06646e6797f712a3efa8000044540be9d3f SHA512: 0aa31a92d97be328b398fff1ed6541a1fed8a732e400965156569da6fb64dbd3bd551fbe6ea7d5e4d2cc9e20fd5b606905679c66a9761f6e3f5229d57055e2c3 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11805 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-influxdb-v1_1.0.0~rc.2-1_armel.deb Size: 2552356 MD5sum: 392b862206c1734af3edef5acc274659 SHA1: 7c126f6d427f73039d94dfee170a48ff297e60a8 SHA256: 8a45b025f9ca4441d04b661156dd3cc5cc229c4e1cf1a79ede1d7947ea5af3d6 SHA512: 6334b685acd726a79427f5ef13f3af272146b0727044e0ac6e2a5b1734210124d8c39337b74d6d8287c9c7dcec5d317b223324bbfc621b12408be84aa37c0136 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11678 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-influxdb-v1_1.0.0~rc.2-1_armhf.deb Size: 2543188 MD5sum: 0cd39b52e51996753507e6e23107f451 SHA1: f4e7b62b66f411ddc6e918fae74a4d79b36267d4 SHA256: 8a523cf848e6def4d885683b5209df5549161f95cd738c4027c26ad2655d0cc7 SHA512: edf610fa40e6a20a946e40cde2ff8ee6868e13543225618eb208b590e2410b588229749bbc540567dfb5b16b3b299ac007c1d4883ff10916ddc4e3d717401c8e 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17302 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-influxdb-v2_1.0.0~rc.2-1_amd64.deb Size: 3803056 MD5sum: 1e170f1eee2cda219affe5b2714f1567 SHA1: 27027ebc66b2508bcb6eab1ea32e0d1171bdbe74 SHA256: 05089c2715b75482e3a4861a1a8451bf12afccd2f99b80c3c6ae796d14d6f6ac SHA512: 14326b47c6807db88029db0e185f6d8f4d0969a533d667015aa6e42fc9d735b2137fbcb84fa824dac8f2f4d895585ab7fc60ef641a7c3ed704e75f4b2d740435 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16281 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-influxdb-v2_1.0.0~rc.2-1_arm64.deb Size: 3486752 MD5sum: 27b5947aa2ac47abea6101d5648ef96d SHA1: b801be10b961457234b2d9be1f4c856d29c0afbc SHA256: 8ce28ceba7ad82cd093e5210ac8e5c038fd05f3d9d99057106dfddb4008a8120 SHA512: 18bb8be2d0285762fad2166c40a6012c9d2719c6fbb82a4596af29be8ca0bc188d89d35b085b1d37d7085dd79ffe1fcd9d960c238f23cd009261dfef8965975e 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15591 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-influxdb-v2_1.0.0~rc.2-1_armel.deb Size: 3469900 MD5sum: 09ea8bad8a82f75f578f1a211c2ff9d6 SHA1: 66fe110525103e3962716b7c136d271f98181dde SHA256: 35754c50b9d227cf92d125d0aa839fe8a505ace15197d47ef6f9b7aa64741895 SHA512: 7da606c4078d7dacd70eadf7ae678a4e17454dbe9c1827781f56adbe21b0598b137221027177b32874615bc4bf7e120c7293b51cac70ae4d07f13520629d4875 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15489 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-influxdb-v2_1.0.0~rc.2-1_armhf.deb Size: 3511804 MD5sum: 02806afd02efc6eec6a1a38943187c25 SHA1: b3c6231ddad33217992fc1cc5e5c3793a86128f0 SHA256: 30715b01a758d0eb9569a2474645bec8584ae251366f9c212c9c8637934cdc88 SHA512: 2e9a5ccfdaccbb2b6199e150504794becfa13508aa7727f2762656608b34c9586c6d30785e18159ddc5c2a2cef2645e81248204927edd584a96dbe6b8401974e 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19383 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-rocksdb_1.0.0~rc.2-1_amd64.deb Size: 4329824 MD5sum: 8240becee575c1c65b5cbaca06f52c53 SHA1: 99bfe803621dfb39d6b7d9d8b3adead6d6f9c954 SHA256: 4f3083262be70930086f47bc8a431025729b362dfd3be8192baf225e3e3eb969 SHA512: 25cc8593bc6a2c33f6b5a73c3f6680ee61de55a520b09fd3f41999a44978775444a4dfd990e2c1be6825dfe74a6d3271c9136ba7ac78f88835e4ab4034ef2678 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17488 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-rocksdb_1.0.0~rc.2-1_arm64.deb Size: 3887416 MD5sum: 8523bf00785219ec0407104647ee8b37 SHA1: b0dec28d77335abc21b392fcdb74afebedaec01b SHA256: b8ca3a7df620e8ebc51b8a2687c1aac3e98322491c7781f34a68d58be8b8b214 SHA512: 8f0a9290521f3e186447e536f96406ced7be16c5cd68a4cf5a7614bc7b39cdb70d18a41a364ea3b289d8b15a65c2e97e5b97d44057dc8133435e0ad8f09aeefa 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15303 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-rocksdb_1.0.0~rc.2-1_armel.deb Size: 3695196 MD5sum: 5383a12acd5c106c9f66e5cb0486ea30 SHA1: c3fb8a378e8c29d9f093367031a869ea275e4fd5 SHA256: 0bfe61dcf283e610e73df0db51bc382443d40c5a025a10fb67d270425734ca2f SHA512: a8320b100a9f8c5fc95e0aa04cfed8b86dbda5b318c887455827b664e21150e89ba1d0bc70d5854c21a9a918a41b1bf0bb7b3ebdd2290457562e30e34e45d04d 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13400 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-rocksdb_1.0.0~rc.2-1_armhf.deb Size: 3798804 MD5sum: 21a9f59dba6dffb3e3951ff05f3b59f0 SHA1: 6194f996cc944a35f5ad836e2ea28749842fc98b SHA256: f7232e1e1edce0951742b220ae32f502ef4e335c9197ed1db1e37b9cafff12db SHA512: 6a9b71a8a7441217c15a396385395affbf39460da8d8dff4d31327f7030eecd5260ac3dc47b99de8d196352a91a200def36738fc56400b56df964a7adfe882a2 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27267 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-s3_1.0.0~rc.2-1_amd64.deb Size: 5517004 MD5sum: 333c1d960bb514762e7f101bec412f60 SHA1: 7ea13862ba90db9dded243ee877e69c4c418b373 SHA256: 610cb7418e399193c229092218002a041cf54535a42c23b3a5584f7254cec648 SHA512: 597f4ca53ddf7d7d8820f22851c2d44ea67768aed134b384530ab4030e19e67263f80b47ba6587b97f9db5be3b320e91828e4e1e6540acfb7f16a1d1894a6c44 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26511 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-s3_1.0.0~rc.2-1_arm64.deb Size: 5231748 MD5sum: c3077ab160eecb909f594fd9a443dc7c SHA1: 337df04ee6ad895c6681ba0167023cb752aabfe5 SHA256: b8bd101f91485ad9f192f2771f40f2c31511d8738b13e66b48aadec59ff804ae SHA512: 1ad7b70c6d73359ab7a4c2801993fb6c31aab43d008233fd8c8c05a3a16b038a009cadc7e8ed393cea79e51cec49a51de5e69a7df99641275a36d627c5fdd0c4 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25174 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-s3_1.0.0~rc.2-1_armel.deb Size: 5088520 MD5sum: f3eaa20701c281b960159708b66dc946 SHA1: 147fdd2b415d1863ac74e22a7e0bf14259245f79 SHA256: 93828f4df349887d02d450100d7cdcaba381cc4fa8b7dbe8a6f440595d5b6445 SHA512: 830ceebce578d5da23208ca2d2da4e7d850ac5bc1a35be37ff95bf5b359d9cc702c68b8385f1cadcb22dc80422a6023107211d73b4a954f64058699486651384 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24944 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-backend-s3_1.0.0~rc.2-1_armhf.deb Size: 5128356 MD5sum: b8b9b28cb38125cc482c8b9ed42e0d9f SHA1: eaf70f58126e8b96630e0c58b6c60de59f2cdca3 SHA256: 2b6dce8bd9d27db160463006c7f301aee70e8cf9316342a8f4f9fd52cecead2f SHA512: 32c8bf2fe25f3cd6b9416a81f52f1564fb934257de8ccb4c999488f9c9bee62aad9d2bdb4fc43239be2cffb027b7ee7e7938b7fb7fee4827203e6e4c69e814d8 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20596 Depends: libc6 (>= 2.29) Filename: ./1.0.0-rc.2/zenoh-bridge-dds_1.0.0~rc.2-1_amd64.deb Size: 5281040 MD5sum: d02c123cfebb5b737b5c072acca5d2e3 SHA1: fb34e7036a6602254ddee4b374c1e5e70c130ecb SHA256: ec1f4c7edf0f298c75135e6400e92ed9166499ff97c006fbd692e36c3767670c SHA512: c2de9be934a7067dcf65a43f1aa207acbd120965b0fa7b9f1cc84a24e1f836052f43602f986fae7366424b5ff153634237740b4890dd854d6bd02ee8eb34ea3d 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18840 Depends: Filename: ./1.0.0-rc.2/zenoh-bridge-dds_1.0.0~rc.2-1_arm64.deb Size: 4773428 MD5sum: 5cab07fdbada698b50ce55df31b10583 SHA1: 010230dab4504665e8a421d594e1f4389883ab08 SHA256: 0c3e8db6badc678b3cd7ec10c0b8f48768eb2468f7ca1009c45d6c5e71fcc6b5 SHA512: f13c8333501bf681b55c3dcb633191f659dab16607c462d1b340a741cf21f733362c9ff55a05becd94dcdc91f970813580bd1f2975314999cccbbf0180737933 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19963 Depends: Filename: ./1.0.0-rc.2/zenoh-bridge-dds_1.0.0~rc.2-1_armel.deb Size: 5036980 MD5sum: fd1647c40a745b2f0428122abc00328c SHA1: be8c295122f346ac4da33af45711986c4c168271 SHA256: 42b5eb598b2049fbf8855d45471f344ed082ba1c6b6be9a2fd42933b21aebf3c SHA512: cb75fdc56bae4d839cbab979d2ce3d6467da44b8ac1af17b091de376b4fea68e14e68da08cb235614095daa3743815830a3986b9f9647e6ec10b80f9d14ed992 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19450 Depends: Filename: ./1.0.0-rc.2/zenoh-bridge-dds_1.0.0~rc.2-1_armhf.deb Size: 5089780 MD5sum: 2e6ff31d6a3bf30e2d0b457938b85c7c SHA1: 4b091d697886f21def2fbd87af772827b750ce92 SHA256: 535c28493ce666b7872ab6288a135e920e5e3cd8ec810d34c6c3c3e0ed91af3b SHA512: 38246d44fc1a67174f58422dfb60a646b42a696c2a77ac9e8fc5102de0e0b37f5c1aa1ce6c2005b51980adb93cd3b064791ef1deae7cc3cceb86ada203eab919 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20530 Depends: libc6 (>= 2.29) Filename: ./1.0.0-rc.2/zenoh-bridge-mqtt_1.0.0~rc.2-1_amd64.deb Size: 4952672 MD5sum: 26a2ffa166ccb19b8721b8ed10e28485 SHA1: 3d46059a987e8672f09e5113c11aeda0b57ed29c SHA256: 23642c01b090218d9fa9ab82d79461399ff534bf6c33e619792a9799e5d21a66 SHA512: c92237faf6ec01cd23ad57a908471c111842dd5729610423fd273856ff528e5bf6673fe60d63679c961d36b77917d953d6ca37437ab3cc07accb21dc8eb58831 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18751 Depends: Filename: ./1.0.0-rc.2/zenoh-bridge-mqtt_1.0.0~rc.2-1_arm64.deb Size: 4479520 MD5sum: 569fb92870eadbdeadbd94b7ab34ed63 SHA1: 12697a663618dc1c31598d5e5643f8919d92018b SHA256: 7bbb40c103904d648e23505c78a2f649842e6a361047b7781c1ca422772a7d22 SHA512: 86ea4d59d6ebe8c9d8e7d2e40206a0f5ab69f221c6db7ca2029f85b96332756e3900c6c9be7fb539cbe2f1876ed36c4ad4662193472d40d69dcd44b3d199ecfc 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20061 Depends: Filename: ./1.0.0-rc.2/zenoh-bridge-mqtt_1.0.0~rc.2-1_armel.deb Size: 4766784 MD5sum: d52ec3037c7056fbf52a20c99371cf3d SHA1: dea5937d19cb2448af90842ee613b15b9c930462 SHA256: 0567d36ee09b37602fa7c6b9ec263a176c6efa6f411745aa9315996a650f279e SHA512: 23c1d53327cbd8a6f35c074aa2eded068a6559d914dc980fe17b25c8044abe3b5cfd72b90c3c67a8438bd41e8f1b48f4cd37790e2332249e9f6a1df2bbd6ddae 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19783 Depends: Filename: ./1.0.0-rc.2/zenoh-bridge-mqtt_1.0.0~rc.2-1_armhf.deb Size: 4793956 MD5sum: 5d7ee4249e6d71f371f9a405e127a226 SHA1: 23d6489b76dc826e67494fe915aeee16e85ba5be SHA256: ca520d3b130b881a71bdebb3417981fad86e7e2a95c111c38d92297e5a7f4149 SHA512: d288e091c4148a34d3a55fc6ebff2f2e2faed3f3c3f0e277a4e45239a4a52ea4343b982f96fe8a20d9546cdde8bc42dade06c50614b21aa525907b4d1b086c9f 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-ros2dds Architecture: amd64 Version: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21153 Depends: libc6 (>= 2.29) Filename: ./1.0.0-rc.2/zenoh-bridge-ros2dds_1.0.0~rc.2-1_amd64.deb Size: 5378276 MD5sum: afac919fee1c5add5f2f38203ac47ba6 SHA1: 7484929acf69b9cc073d44033fcadc715317c89f SHA256: f0a04b8e1c9ef73f722f9005878cabbb8be6b7a14850ea94bb5a2e9bb582c2dc SHA512: ea8bc7810b5ed197192cd40c3bf8d19aa6551ae1597c53c99c1b76773f68891bafdc14b414aa4558adb3345b3dc62e4596a9379a6193df671ab9d53223aff9dc 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19351 Depends: Filename: ./1.0.0-rc.2/zenoh-bridge-ros2dds_1.0.0~rc.2-1_arm64.deb Size: 4879588 MD5sum: 321b001c82f1f0a7dda2c67cfabd5d7b SHA1: b45cde9d6652dffad9466ff324a184b625d5f98e SHA256: ffa3663abfb59b38f586844f1d2707eed809067ab0c9db39ad3cd1a8efb0faec SHA512: 2f485cbc793883ed1bb5caf9daa35da39420117e197c50d0bf7f697c8d756c8e5e09aefa4e3524ec4ba7be958a2d841d723193cf59116c24035f6a521326c4b8 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20494 Depends: Filename: ./1.0.0-rc.2/zenoh-bridge-ros2dds_1.0.0~rc.2-1_armel.deb Size: 5147640 MD5sum: fc9a55f882e6e633ad13344c96b22418 SHA1: fb42af893c33e167f086afb4d5240f733cbaf18c SHA256: 330ad684b8301b853c45c1ccfcd13eb34e4e80858e0bf5e637efe9e7aa039b9b SHA512: 8c78d6a811f5d7b9cb43a4a721749b24d0c7db9a10b3bc1e9c4c965ca0054b830085af8c1b2541ca25f78ca7ae6fa3e7d65bdd3962d9024a5602f5cd3867b940 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19988 Depends: Filename: ./1.0.0-rc.2/zenoh-bridge-ros2dds_1.0.0~rc.2-1_armhf.deb Size: 5200104 MD5sum: 9a7bb20bac12aff647e271ffff7d8747 SHA1: b7262151b280ba3852107b9957c11bac4656e76a SHA256: fdd8c8aed2845c42b88717247a077f89e3b1ddc0fa2212d857e0528dad163150 SHA512: 53422370c00f7688e78d5ef4dbc2750de4267bdcbc75515abcec8087482f4b15600f6add55ba9bb0b71e2c047ff94ddddb9857e09c9bf45e6be07bfb1dd123ef 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12754 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-dds_1.0.0~rc.2-1_amd64.deb Size: 2569984 MD5sum: cd42035a85a04be78abef8cec791566c SHA1: 37fce32816ce0f1dd1c7e22aa8e8ad40889613fe SHA256: 2db8aff491335f4ba9d922546d17d872db83964aae151f15f9b84a493eb2ea3d SHA512: 8b5498917f225b6556d2391ea26efb94d830746495fcee41233a7deea19f19f2b1f6f165507cfaf6d4ad457097431c5d8877069d1700b0c4b3668beee22b3a57 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11573 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-dds_1.0.0~rc.2-1_arm64.deb Size: 2337944 MD5sum: 71dcc183e362440604bb789a05b5735a SHA1: 8c7e28f3fe0d4cc433feeb16feae98ad86287ddd SHA256: d36969c92407ad8b8bad56a58e8974aa4ac32066c4f0a0d05a3ea41e55b3ae28 SHA512: f01c223b408f2b7769e7418cdf6620a7471a911372ab50f47b309879e3a5d0c4b170f759807e176ddeb5e23dc015285ecb3bd4fd602e6ec5d936caae559f92f0 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9587 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-dds_1.0.0~rc.2-1_armel.deb Size: 2183064 MD5sum: 495aab00d53c71254afee42b7cf59769 SHA1: e1984557693d9759f532e293742c6cc69244d8e1 SHA256: 4cd5c032c285789e6b8318232896e9c072b02031675156f1fec1ba56a13626aa SHA512: 4e2d7bb6eeae05c6bf2c6ec7fa4da64ddd2ad54fbfe4c8585fb8bb3219e481cb1a5d084cbc40903f1348a281a9b7832ca1559924d8a28d23a03af3ce50c8ba08 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9207 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-dds_1.0.0~rc.2-1_armhf.deb Size: 2189396 MD5sum: 9a5144af97343ab581b844400f6cb59d SHA1: 40a94936b53e87e2f2e317238681cb9f59c4f8e5 SHA256: 43fd60cda37a46a1164695a4c5fbb6e1b2996fd11880976a865d798ffcfd7fca SHA512: 3e6c0b01b77bc1787ecbe0f2c468bb0d7be624eb50ad23878ec13c592a5a64b155a20b3825814204a0847f4e17ce3bc7eb0a71860993b8cc1dcbedf3d89704e8 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14039 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-mqtt_1.0.0~rc.2-1_amd64.deb Size: 2873124 MD5sum: f58f07af280563b8a128345afe46b812 SHA1: 4db097a764184f218f88a18d2a4f14bf296b10e5 SHA256: a856f39e361b19449b1b487c360efaadfd65cb40d7e842683bbc31f119b752a0 SHA512: 837f6b79958e64e4711d385668bf26389c75b6589cd6f61a54ea2927b135b6efb1ea91df80cfcd68680cbaeb9a6f6c94626d67b18fda77ee991e4a2061f73cc0 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12767 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-mqtt_1.0.0~rc.2-1_arm64.deb Size: 2567388 MD5sum: 0db7d76df8099050e10d2c6852bf4922 SHA1: cabe9d778db4854ff0d318c97ae4da8aedf30b8d SHA256: ffc9b9ccafb9a078e6f8b694b16f5770bb146bc48a6c900c265c9fbb4d6e1c08 SHA512: 7eb8fa0e276f34128abc00e7de2de7bbe309941e64bfc6c3a705131b13acaabf1694369a144194b5de319190a2bae5f37e0530030937844e58389fd627261fb7 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12759 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-mqtt_1.0.0~rc.2-1_armel.deb Size: 2634112 MD5sum: a5e73e52afff58a8f03b044c42c4fd81 SHA1: d31f66a95d28f801fafc77ed2f9f886d14f6535a SHA256: d0245073de2ac055dab67ec2b111b96d3e6ae0b6c49e0a390d936d8e371f04f6 SHA512: 97bf205796abda25e7ace614ce76531ecb12cdbcae582e440c1465c5933cb190a3869afecae5591de5394b551b99a16d0080b205b831113e116cf7bc7812a3f0 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12679 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-mqtt_1.0.0~rc.2-1_armhf.deb Size: 2678504 MD5sum: 0280974c1a3ed03b72eff01c850e9a43 SHA1: 3db149919e096929a912273a9a66cba944ccc163 SHA256: 4b0237f6ae9c6392468a010dffcc0355f4b4df9e936a2eb3e2591f7d75f6af6b SHA512: a6760490c73c3bf2724f8be51df247500922a0f0c3bd44b53da197a0078e751a1fa9fe75258a478837cb1e0dec33b6adbe8eebce4dcb22db5e3ea5dc576af4ab 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-rest Architecture: amd64 Version: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10854 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-rest_1.0.0~rc.2-1_amd64.deb Size: 2087712 MD5sum: 1cea5436c96151b34e448fe9e9983b20 SHA1: 7f88ba8464e4425566e2fff1f1930aa5b2caf0a3 SHA256: f06817cfc3b5a090f6215c85a88db0bfe9db5790e9e7a34e463241d65ae44f7e SHA512: 55957a27b35a179973ce849d0d99bb1b8cd771ae8e5714301f9330f197810a05652b9c9f4df9f707f32ce45ee08b23cc103a7b6f6b64b879a8d3286b1003e750 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9835 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-rest_1.0.0~rc.2-1_arm64.deb Size: 1910412 MD5sum: 19e001b6979bf6fc9591d756d51d6bbc SHA1: cd0fc65bfa0c8454c3b4e99a4ec39488c30e3449 SHA256: 5698bdce73f4bb4211dec7d77616cbeb07bac3f66c6824a77942e4872fd44438 SHA512: d867b1f50842c09185b08425a6194e27a8d34bb5e46d884d67afcc4697324d1b5a988e62c5c1bc42daab5abcb81b6f8e2d6af618cb8813743537b2f97b61294c 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7981 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-rest_1.0.0~rc.2-1_armel.deb Size: 1780300 MD5sum: 6bd14a853875319893c24e0b3b4c74e6 SHA1: 6d3b06c6ea7e172dcd1e5206be57690cad6a442e SHA256: c69340aa25aa9aefac6206d97ecd8295b7083a1f37a5846c411e0ba765fb4ea8 SHA512: ee55160e5c225d4c4312a553170077449dd837664c2884b965af65050444dfc98d8820fcd929337fd71efffcc92cd114048e081e4d7a3b328f7b71acb4e23205 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7887 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-rest_1.0.0~rc.2-1_armhf.deb Size: 1771084 MD5sum: 2f1c58ebdc01dc5c0511796b6b12f35f SHA1: c429de6123d91776019b9fdba1c8aed740988f6e SHA256: 92658786c6dee63cda2afd5a2c2bbc0d0019b7a90c4d9723a5ca44503e5659a1 SHA512: 3b1d3024a4e6d296938582b5d9c529f355862874dca5480377c388bc97d72cffc4db74a617d4d400c106b5b2bbf0c0c65ee80da5f190cbf270296a8c973de328 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-ros2dds Architecture: amd64 Version: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13291 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-ros2dds_1.0.0~rc.2-1_amd64.deb Size: 2661364 MD5sum: 53ef952767060097e60ea6897e7d969d SHA1: 333e204df966f46fe4e178f29b34d05ffec20e27 SHA256: 3f01a32bd7d939929894dbb68e2bea6f2327cee24a8b8c1eb4d31df9aaf643ee SHA512: 8a58c16f61f76bf0e117bbdec6f2bcc583698ea89e5f129bd71b3965783390ce40eadaace960794894526269a8eac557f5a840ab1e2aa9029fbe2bae83cbef72 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12060 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-ros2dds_1.0.0~rc.2-1_arm64.deb Size: 2429644 MD5sum: 67f0ab14b81b8e603137b1626d277ce9 SHA1: 0996635d15c2353ce3336fbcd58d14bef1320689 SHA256: 2992a95b52c0f67430663179692098e89ddc541816a4f816749e3507ae407105 SHA512: 64c6adf259c4881821f2cc489e6c0a0cbd44f34c2e92ffbcb93500dad47817f26dfd9926df68250d4200bab692dcf92ef9643d2215ff49d13bb2b113782926ab 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10098 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-ros2dds_1.0.0~rc.2-1_armel.deb Size: 2283940 MD5sum: 81761b9d6f427efa4a977f2c570ffb5e SHA1: 55c3a8f834a7198ebea6e1d9a0ceabf6720f8124 SHA256: 105f5e31ac8a86379bdbeafa9016cbed8868ca322b10db7b0b7f5ccdcbed9203 SHA512: 7a8e7a18f699e6c42680c0abeff79a1f4f611cd45cf5235b0c5bcd981f7f654bb98ee213a5b2da80e42d4a3e943935a519c94c28df0376b3d9ef7e8fc2240a50 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9720 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-ros2dds_1.0.0~rc.2-1_armhf.deb Size: 2292276 MD5sum: edeb72d5f4b4025b9760105c438b2a3c SHA1: db6b178aea04900896a0e749b698065d31ba3992 SHA256: 210c58703ef005b5a8105d7c99ab5dc88c1f00a183d9ff20885585eabf357ad9 SHA512: a43853f9872581d3ca1a7eea5f476c14892dea7ce301d38df1646305412a7e80ae538b4b87591a4bc7f08039a723342f73f781c38fde7394b3c482fc06714f41 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10583 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-storage-manager_1.0.0~rc.2-1_amd64.deb Size: 1978892 MD5sum: d3616dc117d7b75b71bae86ea6f3a17c SHA1: 8d9720220ad9489d1d6886b81c136fba4a31de91 SHA256: 5a698fec6287ddcfab1f1a834540399cc71912f303e2856e117fd8763d565db8 SHA512: aa1a8888eac429a395a2758255b50a127d0b5ae65bc44398dcf3443e243b958c60b1c15141a71e2d4ffae5ca6f7982a1be5f63d4c24c736b81013a2bb07e14ee 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9547 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-storage-manager_1.0.0~rc.2-1_arm64.deb Size: 1804800 MD5sum: 443bf638500c894be5639b6ec188d0b8 SHA1: 93f5019ef253b274671050ad1d46b749316fa075 SHA256: 7e05c1ad630499d1ab61445ef7fb6ce18834d1252fb62d35f7c49d8ece3f182f SHA512: 10e3ddd514f800828919afa7a426a935b3aaee4d30209ac9619fc656fd048857839803138466abe404bed55ffac70e38789ca042de24c73fc169958fe113d825 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7734 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-storage-manager_1.0.0~rc.2-1_armel.deb Size: 1696644 MD5sum: ea37763a4207ca15d1981114e0024fea SHA1: fc165757d3f02e78cab6b61e471e07b81a7416f5 SHA256: 257cde3bc0f6690d24d45d4a0da99e5030d7ff80e78b6ca664e21c02340d9ac5 SHA512: 385c6d02fc236e2d091ed50a9f82d39c3eea36bababb091da89046607b4cdb34538e92cbc58d8465ae184130c6be7b185f8bb49c713a4385d5b1971283b3ba42 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7620 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-storage-manager_1.0.0~rc.2-1_armhf.deb Size: 1682712 MD5sum: c0811ad418448ae2d5c9e8c3e4b3ed37 SHA1: a6be72135b00c8a3926f046a2902d56757d61128 SHA256: 5414065634ceb672493fc1615bc614e6c25af6605b655303fe4de6b27fe6675c SHA512: 0fef0d283ed13e84820a8f0bc09124ad09f2c115016a6265b0ea9a6137ca594f219671e4c251755fad6f5c460fdb02a2b04dd778eb774391f83538ed0f2e38d3 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13313 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-webserver_1.0.0~rc.2-1_amd64.deb Size: 2519836 MD5sum: 3e7e83ac6e2ab36b859c8a8f2a5bcea4 SHA1: 19ab679e39334e28c21f36aed8c2e6360e11cf5d SHA256: d6853f9d9d7e38d432cd6438c604b9f9a7f812755063b0fb63a0a704fd595165 SHA512: d750dc8cd40975f16560e4db4bab5ef818b0689ef9dec436f34db9f050e749708e09309aca8c4457e12b92501e1f0d32c95541a0e0705f2291484a8e23568352 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12489 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-webserver_1.0.0~rc.2-1_arm64.deb Size: 2349248 MD5sum: 5f5806127c1cf0b1eab84c83991dc689 SHA1: 59434c0c01aec4d492c3826756baef01ac99cb55 SHA256: 7b6a974afd0c8892577962af5651e6532338582ab9fce4af3d9a1e5d6a718d35 SHA512: 0de982a67e5d34ff842fe3c4edef59396c10eca429f5d65f3bba468cfef4c035461a67e91eef6925a5b95681e65a6dfb99fb245aa3e96f7cef9a58ff67804879 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10193 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-webserver_1.0.0~rc.2-1_armel.deb Size: 2145812 MD5sum: f90bce98e2f1dfddd925b39d7543be1c SHA1: d63c57f8bf0551d63ad9d764a7bc5381657b1949 SHA256: 94ad984ad83ad0d5a7fe8b19e580fbedfad8a8e865eea7a02cf55a7c43afa4cb SHA512: 9c21418e558b767a90ce7db273900635540ce036b627a06c2c425cc4db318a880fd3f2d978fad91dccb16896a2c470b404dec35159bfc77ef7a99b9c3f03473c 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10063 Depends: zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh-plugin-webserver_1.0.0~rc.2-1_armhf.deb Size: 2130864 MD5sum: e0a05d256f304ce82853347e1d86d19d SHA1: a057b6ecfdd30ed34eb076cb887fa64153e990dd SHA256: fe0ef60c778b330ecf18285a5f96629dc29a473ebd86077c080a4c55d65e55fd SHA512: 08ae828eda591e149741f2cdda64f2269e6c867c840fca42cda31d3effcb04fcf19c68081f5cdd0dad994765a238a08fdadf75f37f8ffa0820fe265fd73dc45b 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.0~rc.2-1), zenohd (=1.0.0~rc.2-1), zenoh-plugin-storage-manager (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh_1.0.0~rc.2-1_amd64.deb Size: 17576 MD5sum: 7cc0ece94211eda69743f69bed709ea5 SHA1: 4bcd7d365e56a1927e67e80a85e874dec4af72bf SHA256: 7f8e7ecadde69ca4cca4c4b853ecc3aef4a5975a577a2a242015c47e6010b45d SHA512: 36cfea4594099ef4ee978ae1f96f3d75f75809e40bbefa0e4c03745adc5c21f400d7bdbf5bdb7949b886d1274804a2049ee18159ae97df24423b6457cfcae1c0 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.0~rc.2-1), zenoh-plugin-storage-manager (=1.0.0~rc.2-1), zenohd (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh_1.0.0~rc.2-1_arm64.deb Size: 17576 MD5sum: 7bc8a9767c73d9aed71677c18f245753 SHA1: cc7781761f91acf2c9232d747062cb561829b14d SHA256: b94809e86ecb5052fcb5dc2fa8f3611e1cd3fe6c27e9552c64ff0c8aab537776 SHA512: 1ea654ec95356a1014aa3690d0e9fa9cb27d09e8b32c22cfdfaa6ef9db04f40e9ace9f29c090652b7ff2eec5a7a627d0c67806a6877d572ca4e6df04f8fdadd2 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0~rc.2-1), zenoh-plugin-storage-manager (=1.0.0~rc.2-1), zenoh-plugin-rest (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh_1.0.0~rc.2-1_armel.deb Size: 17576 MD5sum: 6cc6823e180097617356b3ccfca1f6a3 SHA1: 34d1d8b45716dd3e1d47ac5e26cbd514d6a63770 SHA256: e8eb549907a24cb7a93bbc856f78e3ed59972de5fded1e42cabb15132b271ab4 SHA512: 856afde50a36811bdd111317c38bf39bd9eed340dba00c3a6c0362ca3e81715e724bc635c064d78eeac5cc44ce7acc514d6f7ba6c259d38b4c27fbceec9b1f67 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0~rc.2-1), zenohd (=1.0.0~rc.2-1), zenoh-plugin-rest (=1.0.0~rc.2-1) Filename: ./1.0.0-rc.2/zenoh_1.0.0~rc.2-1_armhf.deb Size: 17576 MD5sum: 4e56902eb3f6a8e01e55317cb2f50863 SHA1: 763c6968e6a8b50aaa44806f41ecbd7bdce02837 SHA256: abf2f61db92d0e8db1ae846cd7d6b402982cd0a5a8e963c67e08512bd6c48830 SHA512: fa6c87600e6941d79e1319ad9b02f5e41f003e23ccc50459dd88fc4088ba804b506f3d7a36d22df9734cbe74c220fa8dddb432b2691ac0494f4144838a70687c Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18058 Depends: libc6 (>= 2.29) Filename: ./1.0.0-rc.2/zenohd_1.0.0~rc.2-1_amd64.deb Size: 4424240 MD5sum: a77932fb5d36c29ba9bcfc3f2171dd21 SHA1: abd201212cdcdfeb4da88ca572f42177cef25834 SHA256: ac12a5e8b8fd09b3809d7b60801ce775b0a83899aedbd3c5c9e498b48627cd03 SHA512: f70e0acc7b11e8a4f88e4efd043c28a64a4fda3b4528d7cff91e9a33339c0df544a158c589c91f71b94b375a8991311ae5deaff5073462841941877b764fdd30 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16208 Depends: Filename: ./1.0.0-rc.2/zenohd_1.0.0~rc.2-1_arm64.deb Size: 3981544 MD5sum: 22238e7e95d01633cb5f4534135fe810 SHA1: d8a260450e40c9559234dffcba141b82bccdf7a8 SHA256: 7e0ba86873f48f34819e603b9c6d086c5d519f178f3cdd23de0a99836e27157a SHA512: 36dd068011d32985999aa56dbd922e5191c7057be20026118dedc240881a5d462daac9a6882fa89adf34b93f48cbd60e92e846c6eaca1d414e1d1d8e65dc3d27 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17556 Depends: Filename: ./1.0.0-rc.2/zenohd_1.0.0~rc.2-1_armel.deb Size: 4327564 MD5sum: 762c2adc251817f9e6344d1e371084ca SHA1: 22c3ac6383c59c14649624e47c8f1f2a15c07b3d SHA256: 0dfd7ed1973de511f9b3ab1c90de82340543d48b041df3344420f65a1599ac36 SHA512: 9df3e0dfa7c9aa0ee060e0474d5473c1941e191287a68468a5d3f8722c814f1ffbbbead5cca24b06af5afd276bbc1983d6e16984e0307ad01e340a7e26d41ee5 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0~rc.2-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17344 Depends: Filename: ./1.0.0-rc.2/zenohd_1.0.0~rc.2-1_armhf.deb Size: 4386684 MD5sum: 30e06845cb6f9026f82d5902897cdfe2 SHA1: 9859b40599807785bde2c85cf44374ace5eb5e23 SHA256: 3044d14665383a80c20998f2ba363177371e64f8488cbdb38dd5045df7f92bfa SHA512: d9db308c16a74d3f84faaae33b5f682426ae3e5155807f4eacc3e5724e5f91f9a1b774c86a6c31bb9164023b3d2788987e08c918beae5d9eeef411d83cf6e9ec Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0.10-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 333 Depends: libzenohc (=1.0.0.10) Filename: ./1.0.0.10/libzenohc-dev_1.0.0.10-1_amd64.deb Size: 45736 MD5sum: 6981e60262969cde4b63eeec8b70b4e7 SHA1: 0555d1ae66bb0016c27e72eb6e6d2b07e81ba98c SHA256: c8c741555ddc2caba9acf4f04367d82e72ee44c47a49fd141701db66c08878b8 SHA512: dfa156c94ede266373f2a1aa7ced8bdb895299c71994e187568c8780d2cab0059b66bcb9a1c0b5e7fc87d98c9810d5f80d102d569e7b52665d4a75a08581ab2d 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 1.0.0.10-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 333 Depends: libzenohc (=1.0.0.10) Filename: ./1.0.0.10/libzenohc-dev_1.0.0.10-1_arm64.deb Size: 45736 MD5sum: 998d4643ed6b886580641559b0a9dcea SHA1: 06cd67ae413ea97e1f6d674446b997d0f48f1ad0 SHA256: 1d05202fb6fb8b9334af469b5f50093fa1b8a1abb23c4e7d92118d7d2bd38c76 SHA512: 394d88f550bd7d801effada7be8ffcb886b773eb361b851b8e544b735b6bb736b3e81021e6f262d39ad1740ae9d8032cda17e9b88a0ed18e2ce4bd415f7304ab 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 1.0.0.10-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 333 Depends: libzenohc (=1.0.0.10) Filename: ./1.0.0.10/libzenohc-dev_1.0.0.10-1_armel.deb Size: 45760 MD5sum: 93867cfb0f508f0cb73b211b161381a7 SHA1: 5f163452faba5942250714374e457c6462bccd45 SHA256: f6b66a172d8348777e20caf337ce436dade10fdcd6e91afa654b24d080d3387e SHA512: 671ba9a3bf7cb2cdba4a0f6374fbf86e4c584ec30a4980ad6dde360c6b0263bfa917af205bed3ab7f65007ab148d7255d61d5c4ccb637784be1bd3b57ffa848d 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 1.0.0.10-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 333 Depends: libzenohc (=1.0.0.10) Filename: ./1.0.0.10/libzenohc-dev_1.0.0.10-1_armhf.deb Size: 45760 MD5sum: f8bed7fa3c9524666a9e8ffe1070459b SHA1: 9ceb905186c44a91191446a95336d88b6e5232b8 SHA256: 933917d54e9cc831c39d5f57d5c671b98d9d6fafb2a3659b51ff5b51c1f13dbb SHA512: 9dba2441f2e212bde81fb6830ff009d4bc0609cf4b6358f5ea09f0006cbb7b051fce62579cb2774859ebc7b36757926353339fc14108ea704064e461486ea713 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 1.0.0.10-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17292 Depends: libc6 (>= 2.29) Filename: ./1.0.0.10/libzenohc_1.0.0.10-1_amd64.deb Size: 4252368 MD5sum: 9ab053786eafdf61196377a661bfae3f SHA1: 4e87b184b510061126a8a75dfd893e7ae5cd85f3 SHA256: 63676648574cbd6de6f2abeb7abc89b04ea1b5832ea280989a6add49388cdeae SHA512: 4383a6a17f060b30a57336d6b410c00df2c4362da43735fee0a02154619fc55f5eecd5d59527af1cef8b712028744c27f96506c317a446babf0f4a69a3550e38 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 1.0.0.10-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15739 Depends: Filename: ./1.0.0.10/libzenohc_1.0.0.10-1_arm64.deb Size: 3833432 MD5sum: 89b10cc0e85d24bfea382075e251e749 SHA1: 87638e45387c0a0c9ed1083fd5a504725b75fb39 SHA256: 8e7a7c11e8d87d6f111aa123e26ce3cd70e4b6a1be089ac9ee0dbc70d8533880 SHA512: 11e384be20a6dbd2fc09dff14b71b8a80a4644eedb9d359cb188ff36a8a9b17b2a2b46b3fe98feea12aa4f205a164f93049a550d9596c1c21c91e9fa2ce43337 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 1.0.0.10-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16862 Depends: Filename: ./1.0.0.10/libzenohc_1.0.0.10-1_armel.deb Size: 4114668 MD5sum: 427d539eb9895ec670df3684600468c4 SHA1: 0fc0058bb19f6f4896b3c5ebca91b641c6488a11 SHA256: 5ba15109601aa22df2f67e7ad133577c2d4c8274d8a4c39466a85fdd93be8d39 SHA512: 53909f4e5d472028672b49cae156b9872a8bdb43af092ca83b7a5fc73bc1a9ebe29376a27f2bcc201ecd367140e8500354ad5ceceac9793634a82336d8f8f7be 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 1.0.0.10-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16646 Depends: Filename: ./1.0.0.10/libzenohc_1.0.0.10-1_armhf.deb Size: 4147316 MD5sum: e643afaced5d5411019bc65a233201c0 SHA1: 6605375b86992cbf1446fbfd614e10152a80911b SHA256: 169a2e06ff440220fffbbc6e0931bd106908c577b595e89257c304396819f9b0 SHA512: 10e7ef07f568ea1d092ede849c0de6179eca4785b20baf169d1cffc6bc02d73ba906d9e61c3b0ff8b6ec9efa6fc0309e55c6efad11898ae74c5a9fed58552d20 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: amd64 Version: 1.0.0.11-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 335 Depends: libzenohc (=1.0.0.11) Filename: ./1.0.0.11/libzenohc-dev_1.0.0.11-1_amd64.deb Size: 45872 MD5sum: ff8572b9f851d23fee4ef454c66704b3 SHA1: 30688465c0d306f747a151c930f86269bf96bfe3 SHA256: 33ba515512722792c12daed721f7c482bf675fb14592b9bd69a4643ec60f0ad6 SHA512: ff3de263b037baf012ae64bae4cca9e1f1e0b52a3d5b2e63e3788ec0778fe864ae63509ca634db281ad71949ae71701ad0ba9a7776b773ac33ce27fca90ea69d 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 1.0.0.11-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 335 Depends: libzenohc (=1.0.0.11) Filename: ./1.0.0.11/libzenohc-dev_1.0.0.11-1_arm64.deb Size: 45884 MD5sum: f60f7ed297e8211d37a796c31d6fbcbc SHA1: 529564becc5618c04eb9fd63e75a3d665cd41b22 SHA256: efe23ae65b82162c96b2d1a1f43e9c021437619004be93c7b064366c7b7bddf3 SHA512: b1e0a29458f178293a0d459a67453efe86423e23e067df9d0442f777ac655ddf708b1fd24bf0c2757a3a7df0a2a7819545ab29352687aaa4d7f9e71926f8a4b5 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 1.0.0.11-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 335 Depends: libzenohc (=1.0.0.11) Filename: ./1.0.0.11/libzenohc-dev_1.0.0.11-1_armel.deb Size: 45872 MD5sum: 93cec6ec533fdefd6227a065c897146c SHA1: d505dbd2ae181636f2c30ee7a635129c6da20a38 SHA256: 05725623ddb910c0a5ab2f2a3deea18a1b30ec16ae1a28e482349518fb1b4440 SHA512: 573d81568dc8851f96caed6c44f13600a023840b147f6026e4d72892a2bd93ff267f9456693df1e53788214d802ad95e8d08067efaf62f9fd8a94a99117b1e5d 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 1.0.0.11-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 335 Depends: libzenohc (=1.0.0.11) Filename: ./1.0.0.11/libzenohc-dev_1.0.0.11-1_armhf.deb Size: 45872 MD5sum: 650b789ffc8960e88244d79db8725a3b SHA1: c801b2996fbb8151ab72d5b3d1b26f614f693850 SHA256: 1d07b8daa47e90ee6d0c8ef2e342259ccc4344065a56031746e6f7d67b75b3ba SHA512: f368541363831d03274d4f9c9d5212241485385ce58240281c7ca2d2d0f1c8dd7c1d4f23a264cf52f194e59bc0d782b3df98704b06219b408a80fd1688de4aad 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 1.0.0.11-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17305 Depends: libc6 (>= 2.29) Filename: ./1.0.0.11/libzenohc_1.0.0.11-1_amd64.deb Size: 4252856 MD5sum: 421eb59bc4cb8b59abf26ef229828633 SHA1: 76a4d3b3b0efc41a0359e76146721a04e24ad296 SHA256: 818cae71257eb15e06aa69b8ddf0cf58114afdc56ab98611c099bbde23090dbe SHA512: 038ac12caaca9b90bb9f9a09f65a2c77606e737bb04de0f769698f4c59c0f73afe4369b294afd5b8ff76e295ffff3b613776e18268d7077846b86ff9c9474d10 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 1.0.0.11-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15743 Depends: Filename: ./1.0.0.11/libzenohc_1.0.0.11-1_arm64.deb Size: 3842408 MD5sum: 70609cfbf91d6c937ac27262b657cbf4 SHA1: 616bfc9f7b59c1a1900674250e497e55f8a1949b SHA256: fad3fd2663dc659ea8c4b7273d233c1fb30ec43f3f777006aa0da40845c1be2d SHA512: d2ea9b23ddc2264d09d354d198cd4543b8c4cb83fd9957bc998cd25530b3a008239c7d733103948b72374a515ad3b097af8404a26ff6558a2d6406e98266500c 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 1.0.0.11-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16875 Depends: Filename: ./1.0.0.11/libzenohc_1.0.0.11-1_armel.deb Size: 4117980 MD5sum: 2da30ce7bd770676655fec01fa7f8770 SHA1: ab1d51116de95d768affb5b8a945233cee694f83 SHA256: 7b76b74d2dbbaa25ed7fc139596b2a94b9cba4697860f5226b7c252ef934eef3 SHA512: 8e25e3d37a95c43f8c073a864e66f0fd32080162df191a18169333d16f9077d6bf17c4e5d1db19e12fdf3b334a1638def50cdade0cb02802d470bda137fe3964 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 1.0.0.11-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16658 Depends: Filename: ./1.0.0.11/libzenohc_1.0.0.11-1_armhf.deb Size: 4147500 MD5sum: 571c0aad8b4e1a611ea28f07ae487d9e SHA1: 47ecdcc3d8237b3e55cdf3b20956498ee19e6ca2 SHA256: ad50c56be90527d10c6eb2e69f9a70b79b3397cd30014533c89508fe60242392 SHA512: e7e89bc033196f830ded3f468807941264528e96a1dbf35b4167ec85323da0f6413e49bd05eb3a116b808887faf04fc183688b01f211172bcddbbb896b272e71 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: amd64 Version: 1.0.0~pre.12-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 339 Depends: libzenohc (=1.0.0~pre.12-1) Filename: ./1.0.0.12/libzenohc-dev_1.0.0~pre.12-1_amd64.deb Size: 45528 MD5sum: ea9c158fe4756ac4c578d64d5e916fc7 SHA1: 87741ef37d465ffc7abea7da176e5cf73a594bf3 SHA256: da0d693a5d520e7a182f9002c22628c3c32458620b1d8cee10217f796feb426b SHA512: 59503aecc3db3966c4a4aab576b817d31c0969ca8596e94357391691d8c9907eb44f6ef49dff5fdfd8ef25f6ee131f417cdfcb395843e6c550a76778347f47c7 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 1.0.0~pre.12-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 339 Depends: libzenohc (=1.0.0~pre.12-1) Filename: ./1.0.0.12/libzenohc-dev_1.0.0~pre.12-1_arm64.deb Size: 45536 MD5sum: bb30e5d063079a900dc4fc2ae17e8219 SHA1: b8c4300ce405598f303f83614db08999e8a5292f SHA256: ba3f3885757f60de354cdc4b897f68fe26cb36ccfbc679ed93826068c194cf2d SHA512: 3bcd4786eb8b3c1e3f5c536c5902f36ea3fe590828db74f8bc1d1ad43c01396b24a94e09e5b68a68ff2251faec4b82eb738b5074cfb20dd1d33afb33240e71e8 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 1.0.0~pre.12-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 339 Depends: libzenohc (=1.0.0~pre.12-1) Filename: ./1.0.0.12/libzenohc-dev_1.0.0~pre.12-1_armel.deb Size: 45520 MD5sum: 80c10064bf2275f61905bf4a22a30f22 SHA1: 76308ea2f258f68239f0e52296c4281197d6fff8 SHA256: 9b858323f6b9c2aca01c46a9440038b6e44ab23739c6a383bce77bb45ae456f6 SHA512: 216288ad4e28539971671eec1d96f8c4781a56c5b10d055527bfa1307e056358cc2f27e44034a2cae3238639f92303678974a92b7a27decee093d9b0a8831a1f 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 1.0.0~pre.12-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 339 Depends: libzenohc (=1.0.0~pre.12-1) Filename: ./1.0.0.12/libzenohc-dev_1.0.0~pre.12-1_armhf.deb Size: 45516 MD5sum: c6916f04472a35e7805e5a1379146e8c SHA1: a16ebf7fa9036846462cc1bcbe4b91088a445b96 SHA256: 785f8033f25b1f19ff2b8034fb3b593c678bb865cc12acc5a9265de712be324a SHA512: 09b1d5e66b05f9e3eb57239322c1d398daaeceb29e4e5670f06a41eba07bb356b7a996dabbb1a205a39ef91675cd43195c533bf28fb8c9957c4145defaafe633 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 1.0.0~pre.12-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17357 Depends: libc6 (>= 2.29) Filename: ./1.0.0.12/libzenohc_1.0.0~pre.12-1_amd64.deb Size: 4261016 MD5sum: e93187a173d3a161fbadad7c90a2dd09 SHA1: 39043bbd320caebe55007f0c39c2cec1cb7a97f0 SHA256: 39ec7c242382c9555c00b5f72ec06a199a063dcad2c0e551c617378178d30b51 SHA512: 00188ab032673e04bdb5b3f81b51458b774f2e5e2732fa68061bf493c40763dfa28bd290758a401bf29a36486a43c85acfb05b93b4ad465dabad91db2947c7b3 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 1.0.0~pre.12-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15790 Depends: Filename: ./1.0.0.12/libzenohc_1.0.0~pre.12-1_arm64.deb Size: 3842320 MD5sum: 1a8c80d44f86b6cd758cba44ab69c834 SHA1: c9a39658e14f7b608ceb92bcc7c16f81fdb9b325 SHA256: a3fb5bea2b5d5cd00097f8242f6d8caf26ae5299c2e7f61307a669b5328ca498 SHA512: 2dc5960bbb7e2ccfd87cc79e8ac6cbef1c1e5ca08c257ca9205f76f6acbde3983da6016944b1a3c31f9f323fb48a2af46d236469580627a1fe39f841f122298a 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 1.0.0~pre.12-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16931 Depends: Filename: ./1.0.0.12/libzenohc_1.0.0~pre.12-1_armel.deb Size: 4127416 MD5sum: dd9a3e638881e8a8a4a2a61832b2e694 SHA1: c3e63c3e5274a9691681cf7c8044a4aff4cd86dc SHA256: 942fdba655d0f41a0805df15c88933d58a3e034dd2e629193e336bcd0699cb0b SHA512: ac1d5f41e61f5eab000ffdc54fb3ec237d9eb6770a3142826dad9d1bcfadfb49f14b6294a93548c5c21eb9d5aea2eb9add5198724666d8435f0fbb75c5e1bcbd 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 1.0.0~pre.12-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16716 Depends: Filename: ./1.0.0.12/libzenohc_1.0.0~pre.12-1_armhf.deb Size: 4160240 MD5sum: 78fde3e705e144479e269371f80edbd9 SHA1: c125270b8e4a0d53eb448a2ccb2b7a2c141ef7e2 SHA256: 33e6e119a057007b541bc3488678318a07825077a0c0cb7bc78421380e0f671a SHA512: 44769d7bd314db50f95d6b69ad45b89cb6897293cc2ced8f85ed4adbbf4265f2365090ba246842cce5fe7a5c11b1daf7b278db22614762b6cf1e0c5cc2540027 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: amd64 Version: 1.0.0.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 240 Depends: libzenohc (=1.0.0.4) Filename: ./1.0.0.4/libzenohc-dev_1.0.0.4-1_amd64.deb Size: 38532 MD5sum: 0d425889e933555bb2cf5ce3cb6f2bc5 SHA1: c5b5ea7c37f83d64fe694b124c8595231334d38c SHA256: cb1d5722a4e2b3f17792511d967e0c7194f4c228977c13bed99115bb797246e7 SHA512: 1b2950f0d4570651ec99e4ad34e84e37b5c193d3478629b2286c6d957a1ec874681da985b95552887cfbc41814709cd665656ba80ddb1d95788223e7695e741a 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 1.0.0.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 240 Depends: libzenohc (=1.0.0.4) Filename: ./1.0.0.4/libzenohc-dev_1.0.0.4-1_arm64.deb Size: 38516 MD5sum: 3131d0f8f32b4a3c849d0efa61761dea SHA1: fd8d9f266b978ec7443051b958e0c67f280a9281 SHA256: 3a2b54bad84ca522926957965f4cd810581210773f79bd72ad0229fe67626e0d SHA512: 781ea860366412f6776858b5fa765f1e9cd64e0f6e0f11c96a57962325df2b559e5d01aa42867ba567e8adecd7f3a189c06120063376f0890fcb45317c28a84a 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 1.0.0.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 240 Depends: libzenohc (=1.0.0.4) Filename: ./1.0.0.4/libzenohc-dev_1.0.0.4-1_armel.deb Size: 38532 MD5sum: bc3afbf94e2d1088d062852edfbc84f4 SHA1: fe8d1ab6e2d86df55db9455c3fcaf6be14f62245 SHA256: ad5778718e892e4b4b45636ac26f1f22370bcf8959a99c32043e3f03e77dd2cb SHA512: 29a0cbf34c3cf99953151cc1531b17abde7667c09b4733311c96379e9bc8baf6822dfbeb1bb27eb1cbf405752e6f45ca240f049b7d9277d70c645e0a3ed5fedd 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 1.0.0.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 240 Depends: libzenohc (=1.0.0.4) Filename: ./1.0.0.4/libzenohc-dev_1.0.0.4-1_armhf.deb Size: 38536 MD5sum: 94773fc621d82e91a9f8f4d151e1b341 SHA1: 0e3f63640ff554b5f01555e9318271d7f5fe966e SHA256: 61eda859988d76e18a2d020dadee8ebd049465b50429c1b8d3d05ac0d54f461d SHA512: 0a74d4e77bde5025a31617b6b84cd4bed1011b3ae0a23ad40dbdef6e97f9d7b1d0e8431afa1481297e2899cb206df3d04bc26ccda27772ebf82ce7c72712015f 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 1.0.0.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17686 Depends: libc6 (>= 2.29) Filename: ./1.0.0.4/libzenohc_1.0.0.4-1_amd64.deb Size: 4318476 MD5sum: ecb5f227ff4b246b719bdff0b95f7322 SHA1: aba1368e067b81ac5a373694585c81860d6282f9 SHA256: bb373bd5ee91050ce988205977df690d10c88104f381d06b29ecf3fcec867e13 SHA512: 6eab73e47ff52c838fb7927511287341a0ddf269c602ad8d1498cbba71049d8de47d4838b8ce3929ee73c8d370b8e6e209cf12a244ace43087541429fb173bb8 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 1.0.0.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15866 Depends: Filename: ./1.0.0.4/libzenohc_1.0.0.4-1_arm64.deb Size: 3878844 MD5sum: c24138828941a5a22a244db0d2d73e73 SHA1: fd7a3570531bc7c242716a8b0beced2a26f1aad9 SHA256: 61a8f505ae6612f27e0ea878576465b0cdc6ca94d482061c4df4211f22f8fcaf SHA512: b554b0f851ca98dd2eaa236e2cbbf272517055289a477a426808e35d43f64e337271688052c79e699415a65ba404a2e923925bf6ff381cd2d0cc4991f691889d 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 1.0.0.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17102 Depends: Filename: ./1.0.0.4/libzenohc_1.0.0.4-1_armel.deb Size: 4194120 MD5sum: b81dcbe11b30b46d4da9c05fee7ed145 SHA1: d62c8d663207001b8ad91348cff8f89431750aa1 SHA256: 9a0da7cf7f7fae381ade8711fa7c051da9e9de47d1638f8e309005c712b3541d SHA512: 4c0e79600517c4c1765216586f7b21f236e736793fbf5d2fd1a534a562d0d8cb58c2d888846f63c20ace72cc07d0edf5c3246b594ebb488edf625e7b87f6f195 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 1.0.0.4-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16882 Depends: Filename: ./1.0.0.4/libzenohc_1.0.0.4-1_armhf.deb Size: 4233952 MD5sum: 82be67e48f8d8e5090cd56884a953d4a SHA1: dea8ecb52c66702b080804d6ab2cde038a140b8f SHA256: a94dfa1b2445ef63f4f4197cff7de225dcf70131a9cd57b8674a04ec1aace67d SHA512: bb7119338f34f7c258bf17007b2b38fc341b99499df2dbc98e841131cb80eaa611334b954f48dd43ff137be0b64d6bbff8318efbadfdfb53cb9c51b43eea9e79 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: amd64 Version: 1.0.0.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 241 Depends: libzenohc (=1.0.0.5) Filename: ./1.0.0.5/libzenohc-dev_1.0.0.5-1_amd64.deb Size: 39092 MD5sum: 51543a02d07ce171d14da5a8d12a3d86 SHA1: 6ada189537d804fb4ae8653e1d94663cd2074564 SHA256: 09a7d42ee47eacaa808b07bbf5021cb4042b428b0943793eb85d0acbae0d035d SHA512: ccfbd1895d4a2a2130e0b3debc2d60c4b5f931258b10c5337e382887535ac2e5a5887fac4c2edafd4ee684edffaf4306d5eba566424e111d859082cb03d555ca 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 1.0.0.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 241 Depends: libzenohc (=1.0.0.5) Filename: ./1.0.0.5/libzenohc-dev_1.0.0.5-1_arm64.deb Size: 39096 MD5sum: 133afc431ee208a43efacb6a799277e8 SHA1: 803916753b782122b2167b68613f5bcc244a0ccc SHA256: 6f63248ca92900273681becfcb41371b86c6600360ad6292906db5f88238a54a SHA512: 5187daf72a5b44c3a584f7f7d09eb31c52a2e46991607f4924236acec1a5374be61a7646c08b502cdf792197f832852bb511e823779e8eeb5315d79619fd3d1c 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 1.0.0.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 241 Depends: libzenohc (=1.0.0.5) Filename: ./1.0.0.5/libzenohc-dev_1.0.0.5-1_armel.deb Size: 39088 MD5sum: d2accb18c93279f5d820f564c34db6d2 SHA1: 77abdd3b328c0ef8756ff9fd34d920339f1a5505 SHA256: 7eedc0948a5dca5e3fc35611b47a2d4a96f0e64e77fb111e3ed049bc4c7c6ea9 SHA512: 3531ebc7f8e2f310d7ee1e27c1e6f1376aed82ac0416b5ff9d3db53b5f3fa4e02facf6f5d3f8487ac53b99fdf3bcbb8eae15506267225d280a0ed009d5a5bcd7 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 1.0.0.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 241 Depends: libzenohc (=1.0.0.5) Filename: ./1.0.0.5/libzenohc-dev_1.0.0.5-1_armhf.deb Size: 39096 MD5sum: 563217867782daaec30d9b8de6d52138 SHA1: d9f5241dcefd719af418faa974f079897b9a8047 SHA256: 044fa182155aa3029e1e5b7caf65d7822460dc45725b4155198a7399e0ab2ca4 SHA512: cfe58d45f44551e8fd52b5ca8d3c3546d6bad32429683edf1b02470f645275bfc38ed24ddd588a955461a0dda423913a3da004c15ffcda3124003e630726c668 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 1.0.0.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17827 Depends: libc6 (>= 2.29) Filename: ./1.0.0.5/libzenohc_1.0.0.5-1_amd64.deb Size: 4347244 MD5sum: 807d257263eaeac48f821f1df11f23a0 SHA1: b521162527e8e556391eeec11f7dcf66435c3b1e SHA256: 6dfb0205151c3ee4425e992a623a8706106e7cf9174be3dc07ff6038075793bc SHA512: d4442cbfec0211feeea911fc24ff8a2f4e2f4b4896caaf1a40a635598196f213247eb7f22486a410bad73bb7db09394da5b25744e6aa2446be925ab3bcf6a3ad 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 1.0.0.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16034 Depends: Filename: ./1.0.0.5/libzenohc_1.0.0.5-1_arm64.deb Size: 3894512 MD5sum: b04ec7e07a3dea91a72f313b8fd26464 SHA1: f4ba55bcc671e7934bcfe8de9f2e9d5632ceb18a SHA256: 7bf1dcbb47d96a98b7f94fed6a2229e02fb20665ed9673ab7e1cb8466fb6261a SHA512: ebe1e9d1160c303aae14bb9e96ac8c8003a7ad973ecf57c5a0563e6b6c42cf7f2a1007cb9d042b40fbb13ea91ffe7645581292a75681d9f6ad8a08e3bc20c6b1 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 1.0.0.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17246 Depends: Filename: ./1.0.0.5/libzenohc_1.0.0.5-1_armel.deb Size: 4176404 MD5sum: 360994e6687c209dda295428c95f947b SHA1: c19050a98771e74fd599ff8a97c0b73aedbed79c SHA256: ec177d838f4bf9467c6c1d77059cf56e0a7e1ab31008834a33bbf22df4ddfb37 SHA512: c3efccc8764423b098c6f4d1e07392925f683b4a260af7c1102a22ca1ce3236fc3f35bc1b768b2033bfa08943379867bf07633fb7e93b58d5bb4de453bc67496 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 1.0.0.5-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17027 Depends: Filename: ./1.0.0.5/libzenohc_1.0.0.5-1_armhf.deb Size: 4210216 MD5sum: d75d1426c79c1553bc12e4fe969252d0 SHA1: fef5962404eb14913b06825955fa24bd12b6f1a2 SHA256: 2c46b870bf6902e02cab3b4cb7aa13d87e78690704ec9a27126b6a7a21d047aa SHA512: eaa9281ce699ea3a349620b1dc6a8c90cddd620a5f35a8726bc2a70520f3262b57e1a74fff39715db743b08707409efff0acaaef7ff7674bf8c9a255180f1479 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: amd64 Version: 1.0.0.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 247 Depends: libzenohc (=1.0.0.6) Filename: ./1.0.0.6/libzenohc-dev_1.0.0.6-1_amd64.deb Size: 39668 MD5sum: ab580a2f8d536a7a0893a6cfa8c70649 SHA1: 44b15bb4b91c6e64f03bb46cd9298439ef738b6e SHA256: 4a79b9b9bde3300c80402f79d51b28763d6bd37666cb1920da4a4bd604bf6d8f SHA512: 9053a4efb1cb931f2e198b208b77815e875cfa58b9c62ae5417001dc19d32ddf383fdac745dc3beed8954590151bcafa293e779fb60a6a73a9eff30202268294 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 1.0.0.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 247 Depends: libzenohc (=1.0.0.6) Filename: ./1.0.0.6/libzenohc-dev_1.0.0.6-1_arm64.deb Size: 39664 MD5sum: 35abf2021f2283d9724cfabd660c0367 SHA1: b978dfdb542b78c84d06a0628a6e55a95bd57ab2 SHA256: 5c4bcd29563934786d59f1576ad9eba0c09f2d66d47a66c16472e5c1c3c48f5f SHA512: 323c0d49bd4f1c2937ecb9687035d7af58b118fd30368b7031161fa760d92f27b4a665860bdfc44855147a1cc1bcb7f2a066960a0eb5e09ca4f413404626028f 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 1.0.0.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 247 Depends: libzenohc (=1.0.0.6) Filename: ./1.0.0.6/libzenohc-dev_1.0.0.6-1_armel.deb Size: 39664 MD5sum: b06fd926883013be26c97164b6545e93 SHA1: 3df67ba7a0f10058444e5df3258fb33484744e76 SHA256: b93918b4f937d81de8d3b96478f982ffcc0cb41ccc9d93b8c80632ff853311bc SHA512: c8ec938d8831e1437c7b0ba2393b1ff16647458191446f34925a888a871e15c58e3f0ca0075cdcefb6bd99f01c32dcdcaeeb747aac8a7673e77ff9889b5cd3ab 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 1.0.0.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 247 Depends: libzenohc (=1.0.0.6) Filename: ./1.0.0.6/libzenohc-dev_1.0.0.6-1_armhf.deb Size: 39664 MD5sum: 48d9cd625aca51fe11212cdcbae3a69f SHA1: b06a52b5a05ba407692b062ede8bdc0ab6153d49 SHA256: 198af96cfea368dd68fee97964e430d96180211c4a4aa4022470fded7cc85d76 SHA512: 121c4e5f1767fd497a85845a3bda7fc51c2c6dc6a52b000088846190d74b4339ad15e6f58d502a95db8bc940dd31e6f3d58cc8846abb7484fbd54ec414de6df8 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 1.0.0.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17889 Depends: libc6 (>= 2.29) Filename: ./1.0.0.6/libzenohc_1.0.0.6-1_amd64.deb Size: 4360532 MD5sum: 100a2701f9d06d1d53a69a5d6e74fd7b SHA1: 474f9941b412cbae0fd07fb85be9a7083fe427b6 SHA256: 0f64b63f594b41c82f0fa8661ef5d27fe36ff35da27408e4de2f5ad9fe1f4c8f SHA512: 4e34f99a7983daea2de4f0c088f5fec16b8bf1ac14903bcd13049a7773c8e1078398840295a27e12f95ed7eb16aca470d678eafbcc8f3e0abdcc552bca82f668 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 1.0.0.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16095 Depends: Filename: ./1.0.0.6/libzenohc_1.0.0.6-1_arm64.deb Size: 3905288 MD5sum: 92fa0565b99eed924b79e26f10da78d3 SHA1: a0d7147ca5f583d4aeead4fa15c42bb1ffdc32c4 SHA256: 98dd4bc775b5595067bfa3c7fef9d988f03950a77baca54a7a41cb81a5477041 SHA512: 3cb6ca5b3e0a768a6b4d492bf4a46ddf951c7dac199c091d6dacbe860d8c20832d801378ae49abf3387d55751b53a0191a3aebcbe6503476a558d9762de32495 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 1.0.0.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17310 Depends: Filename: ./1.0.0.6/libzenohc_1.0.0.6-1_armel.deb Size: 4190788 MD5sum: 4c0d095d0f5b2bfa0b86b1d6dbd2f6a3 SHA1: e572e7b3657fe694fc3a84fe1ca86f68318255b9 SHA256: c0d90b0487103957c408607f4bc1a8f98822258246321315c8d29ef86c3488a5 SHA512: b9e7efcd60f95fb460074cfd641b8f84319b652348b2ee9130de8de41ca5016ccbbea56235466f0516a683188606fd11136e5e1f714bbcd68e90faabf19674fa 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 1.0.0.6-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17091 Depends: Filename: ./1.0.0.6/libzenohc_1.0.0.6-1_armhf.deb Size: 4226060 MD5sum: c220b66e9563ecd4ea9d8a9b6ccb4957 SHA1: f50b05756042afa16e09475e2ff4aa5e4abe4ee1 SHA256: 4edd80e31ebbb7eeeea5acb9df52d73e10dc0854820868f11d1a171b90d99dc3 SHA512: 63aaf274727a9c8fc8085dfc56446d592f252f64257d65e8c3495db52d5d3510ff186138a409a98e4d14a499e5470a78e4a832e71c09436fdc1f1a6ddebf8932 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: amd64 Version: 1.0.0.7-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 282 Depends: libzenohc (=1.0.0.7) Filename: ./1.0.0.7/libzenohc-dev_1.0.0.7-1_amd64.deb Size: 42836 MD5sum: a8de817b53cdd98b8ef15758f449ae6a SHA1: 706fce4184c6dc134639b780dd54269e396878ff SHA256: 02be4532df076ae7b7d04b9eb2cfa91661c90714dc3e26af201e7711b40faf38 SHA512: 825d0471a63af424ef3d9f75d6a3ffc66940a472a994420b93d396d4e591697f2a14db3c4db84cdeada615b23319ab6766d36e09aa0a595cba91740def0abcd6 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 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_logging` 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 1.0.0.7-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 282 Depends: libzenohc (=1.0.0.7) Filename: ./1.0.0.7/libzenohc-dev_1.0.0.7-1_arm64.deb Size: 42828 MD5sum: 4ee865a93cd9667dc58d9f79c1f40e81 SHA1: ad2e50a523532605a9b6303525796b91efd37e15 SHA256: 0b5ccef143555848c5d3292c8a6673a133e1012dbf44dcb7efaef716e6ec5729 SHA512: 42250de3a54290baf670df48a50db7786905115cff5d7390c7bfb43669ace727a888ae3dfc5171c552c660834cec91f7227d95e0895055dcea8ea13d04c50d4d 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 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_logging` 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 1.0.0.7-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 282 Depends: libzenohc (=1.0.0.7) Filename: ./1.0.0.7/libzenohc-dev_1.0.0.7-1_armel.deb Size: 42828 MD5sum: f4bcb6fb1c9534c769efcb41b208ace1 SHA1: 0058bb6da8ae7e464a560e2c42f48bebcde8dc0f SHA256: 495f43f719e2dd1b2337f52e2b3d53feb5e8cae47edd6a6431abdcbc58c0ceaf SHA512: 816a046d7ebc8020a85f8d69291c60af35de166c0aa6d331efe4db082c315d6343c4bec5699940820a0da5c436589daba1ea64280f55584a7a4a6050df5b4bdf 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 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_logging` 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 1.0.0.7-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 282 Depends: libzenohc (=1.0.0.7) Filename: ./1.0.0.7/libzenohc-dev_1.0.0.7-1_armhf.deb Size: 42828 MD5sum: f32ad47f65d352885ab3216319ecb7ba SHA1: 8eb0dbd2a2a37f5ac4b9d4300712f31a466a6eb4 SHA256: 255c5b061439f8959af1dd6f8e366acced9d25e5e331919fdb8f454c49658a12 SHA512: 47824cd0af6d64fa2f6e89a50d1ec49eda99629e47d5cbc3f4bf2223ddcc44d0f3596e6a16e4058af89b4ccb3a43f39a33ee6eb68aa9da2d7c627d125047464f 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 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_logging` 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 1.0.0.7-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18265 Depends: libc6 (>= 2.29) Filename: ./1.0.0.7/libzenohc_1.0.0.7-1_amd64.deb Size: 4454684 MD5sum: bd7f0bece7966566b7f7b57189ba580b SHA1: 2ca71218fc4ad3dca448f3abf996cc61572c0e55 SHA256: e7ef740ea0e53344a037623dd43e3d1f0336c93ff970efb78e6ec7742f3b8eb1 SHA512: 428c2103a46e75f9a31cb1b200200f9137d125aab629013fe80201b871bfe7b4bec196c13ac702a59a7e28a80d396037f12b67074742abd460629a6d40ea7d93 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 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_logging` 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 1.0.0.7-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16479 Depends: Filename: ./1.0.0.7/libzenohc_1.0.0.7-1_arm64.deb Size: 3996460 MD5sum: 00f7e3a8c5ef839907060b672af7f853 SHA1: cad701264dcb8d28009846a203b7502af9a365a6 SHA256: d0a09c89404e678cd5e66fefcbd512b28ff945bd6bf59629e43ce3d1be70ea3f SHA512: 571a009141d84a0ee13154b63d48a756e1f80782a6fd9d5126d54bbf61079f727f10690ef9de52fc69f2b5968e374823f42d2a08703c4397144432a181f88369 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 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_logging` 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 1.0.0.7-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17683 Depends: Filename: ./1.0.0.7/libzenohc_1.0.0.7-1_armel.deb Size: 4288716 MD5sum: e7b14983ffe932a535b0d4693385f1de SHA1: da41c3cfa5c6e2f41b0a0aaca57775f23d6d6719 SHA256: 5be320fc25356fda78dab10602544131bdaf0d4032820ed3913406620e3518b6 SHA512: b6f9ec948f1138c29354fae837e358913d5e43baa36828bb2c6f04145e8705f6d88818380742453d754e2b730c2c8c94ac47c33486a994c4bc029b08eb9885d2 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 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_logging` 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 1.0.0.7-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17471 Depends: Filename: ./1.0.0.7/libzenohc_1.0.0.7-1_armhf.deb Size: 4325364 MD5sum: 9cca5868ba6b942354a904ac45fdc551 SHA1: d66bb317a5e2ff7a0675e69a60058f6adc1112d5 SHA256: c77725ec9aaffb0cccca8486855a8d07b8a56a9fd92bd925dc219ec500045cd7 SHA512: 3f3b435123b9fe00299b36ea4747fbad8abb33fd3b7653137120cd00ea17e372e49e28b076d9ec2f5e5d44dbfc0352c3334a14432442fc94c3160d7517b14022 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 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_logging` 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: amd64 Version: 1.0.0.8-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 310 Depends: libzenohc (=1.0.0.8) Filename: ./1.0.0.8/libzenohc-dev_1.0.0.8-1_amd64.deb Size: 44216 MD5sum: 85ec024dbbad9429b326753d684b3d47 SHA1: d37d47d80d6c5ce745464fa399e0075c47009e2c SHA256: 0238780bceb9c2139e04a230f4bc45c76bba5a4f6248d5f9065cfbfa45d62e0d SHA512: 9454f0f67acbbedf0416597d3ea59e9c4e5e075157102cc01149f35d565e0c3adf41cb3e275236ba713e5127bcbe9b6c003076c1ede426b0f208e60d47ce46e0 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 1.0.0.8-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 310 Depends: libzenohc (=1.0.0.8) Filename: ./1.0.0.8/libzenohc-dev_1.0.0.8-1_arm64.deb Size: 44208 MD5sum: af5bcadb3c7e1f03cdf44191568ee608 SHA1: b0e1481e99c325921ced9f88348826decd93ec83 SHA256: 8af77dba6d0e0dc4950cb001f0615bc8bc7c39bd7c00a9a6cc7ebe31640a401a SHA512: 9f9a5253f57699cecdcc763ffd2cbcb84e00dd13f869b9f0eb3229e8eb107ab896f1a854652c5b31a71cf8175263c5ce323e1376bf27dfd32023852efd37febe 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 1.0.0.8-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 310 Depends: libzenohc (=1.0.0.8) Filename: ./1.0.0.8/libzenohc-dev_1.0.0.8-1_armel.deb Size: 44208 MD5sum: 7207ab408e7fad7e4333dfad17793865 SHA1: 0b45f20745ee62f66cace6dd770ed0478e7eaf9b SHA256: 8e68406501261c5243e79bced3b9e601e34b6c732eea53873026d144baa87aed SHA512: 61834259e1b06b8313ec1511165de2fff8f75a847403b4ed0d34320d18c7881200eb5ceb2ccf1dc438fca9f57f545edfd145678c87a091e9d1f8991996913e33 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 1.0.0.8-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 310 Depends: libzenohc (=1.0.0.8) Filename: ./1.0.0.8/libzenohc-dev_1.0.0.8-1_armhf.deb Size: 44208 MD5sum: f94e40398f455bcc6249a909e7abefca SHA1: e32b8855b4761682d1e7d84e5f745983c63f9581 SHA256: 7f38eb8da55dd37d417e503cdb5b6e99dcaad247f86182994433f8ba4ff7f591 SHA512: 6d14cfc073386e58f9a07e910f535de88ca5b1da8d2e86e83cbc37a66f37cc0920de26f479bfc403614dd8b90e16a26fc5b4c18e814acea20007a942054b030f 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 1.0.0.8-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17601 Depends: libc6 (>= 2.29) Filename: ./1.0.0.8/libzenohc_1.0.0.8-1_amd64.deb Size: 4284204 MD5sum: 73433ad3c6422667a5d96b74440b9df7 SHA1: 93618c82a2b8bf8e800bf37b0ead826a283156fa SHA256: abebf3533fc79b21e610c580a8f6e94da5c9e880532dd483cbf37ef89841deac SHA512: d696df58bc15ae941bebbdb70978f8bfdfd0ef17f1a1b2efa4788687e40223c93840613fc088d63e8b6a8d7836a88e2d7b7c830788b9e22cad35147ce8785211 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 1.0.0.8-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15979 Depends: Filename: ./1.0.0.8/libzenohc_1.0.0.8-1_arm64.deb Size: 3848644 MD5sum: d92c08df9cd9ce94a3a20b063d8125a8 SHA1: 3720353e2dcf2e4cf600d839c03f28afbb6b23c7 SHA256: cc3adb4532e68972a5999140a45cfde7da0f6de0c878eccc91fcfded77704df1 SHA512: 92d8f4f6e2055462163244c45ac23b6c72763d6ad5361154f1204b901a30bd78d7a1be4a6cd633511ae0e215370356211fb65345e7e464549429533cc0df38c4 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 1.0.0.8-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17125 Depends: Filename: ./1.0.0.8/libzenohc_1.0.0.8-1_armel.deb Size: 4141172 MD5sum: 506ab341bbb88186a1522d71dfd67a2b SHA1: 2b1dfefc42c474f285570d5a6b1c323bfbb546ee SHA256: d0865db22f2f4a374a3f5f3f35dc128beb2481d5d378d0f4d68191611ddc35b7 SHA512: efaa931fe91598857dd3f55b7972d7397c0ffdbcb7cad26fa0e2d6f257c9b1446ff1439fcedf190fee31226c46591999838d02854f2b9587676eb204b6c05762 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 1.0.0.8-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16937 Depends: Filename: ./1.0.0.8/libzenohc_1.0.0.8-1_armhf.deb Size: 4179044 MD5sum: e0da0718fc2641913017497af9544390 SHA1: 83c64a0a5d59c9a6e3ca94c3050992b45ed6c4dc SHA256: 62341ce6041877fcf72833620c9a80741cf9023118cb6759b477c1a6882771b0 SHA512: f9ceb91ab3f67749a1b00f59aa46c8b7f0080499344dbe69af4e9ce297f527eb0a6d2be394a57350b25028115378380fd50d6f80e9e49e57c71f3059492baf92 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: amd64 Version: 1.0.0.9-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 319 Depends: libzenohc (=1.0.0.9) Filename: ./1.0.0.9/libzenohc-dev_1.0.0.9-1_amd64.deb Size: 44500 MD5sum: 2506155af06f9452a29a594640aab405 SHA1: ecd3d0071a5f483caa0a54ade18c46db710ae0bf SHA256: 21b14f1711260e2c7a348c5b53bfe07ada6b39b9c46346fc174bd1064e689b93 SHA512: 65c621a34a1d1cb127e5571ec61725b4f4cb38a9b38aecc4548b0fc102a1b339de0ccbc279dc73a9fd69cf098e0f9484fa8b00fd2f130e52a51109de621c2a34 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 1.0.0.9-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 319 Depends: libzenohc (=1.0.0.9) Filename: ./1.0.0.9/libzenohc-dev_1.0.0.9-1_arm64.deb Size: 44480 MD5sum: 4f04f0871c7b006f304ae8e8effaf565 SHA1: 2ed7921ed83064f61bb90c1046f00f2ff0d8adcd SHA256: bed70b52cc301e6ae4921ceeb36bf3a36e4291a017a7fcdbb88ee8908c8e3688 SHA512: a732b22d622950c8522293d01645e19971eddb423f5feb0ccab91b2a9a6bdffad8c57127e51bf6eba30fa30fd657d3b5166d3ab64e0aab964ca9a618f7fdaa99 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 1.0.0.9-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 319 Depends: libzenohc (=1.0.0.9) Filename: ./1.0.0.9/libzenohc-dev_1.0.0.9-1_armel.deb Size: 44496 MD5sum: 4211649708cfc427ce8e8463e9dfa9b5 SHA1: 441b86c0105140ceec373a1c1a2805a6a3f29002 SHA256: d01111a19b083cfcc96f3016c8835126b8ae505677085167b1ed2c35fe25945c SHA512: b2cc0a87cab912e84ff85bec81d159355ce0793b676ae869e615004801bb72f2eceb6a48995168a76dbb13258d4332375982810b6d4ed25b2c89a6be7b6bf86c 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 1.0.0.9-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 319 Depends: libzenohc (=1.0.0.9) Filename: ./1.0.0.9/libzenohc-dev_1.0.0.9-1_armhf.deb Size: 44500 MD5sum: b3db2de400ba5168fb30dfc30030f075 SHA1: 117f82216c198d55093cc5a8a8275e15e9d98d2f SHA256: 22d111d87ddbce3072d8f4ebbeaa70a951b82a83ee0c458d3aabad28bbed9c6c SHA512: abc869d13c9121cec91fa36043a403a5daf48f30d3cd8a79d0f3dc3adf5008d67d0083bb1f87aec4c4f94cc3690f6d1b660f29c9f7b8f8c9035d70adc3cbca6d 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 1.0.0.9-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17381 Depends: libc6 (>= 2.29) Filename: ./1.0.0.9/libzenohc_1.0.0.9-1_amd64.deb Size: 4271328 MD5sum: a68466f8e36cec1ac7d6905749a2106f SHA1: d65411c6a551a5347f66929ce248591af435ec09 SHA256: 3f1edf2f0c3be74b217e69db934733241c3c77f0b3821af687f60d42e4854d4a SHA512: ffc859cd4acd5671a16842e98bd896c452e19a18424d40e8ed61c563879d27c4514d4cc7b6528e34d50e400acb4260d0c195fbc15f1aa433f1dd270b3f6ccc4d 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 1.0.0.9-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15826 Depends: Filename: ./1.0.0.9/libzenohc_1.0.0.9-1_arm64.deb Size: 3849592 MD5sum: 73ed3f05ec5603fcfb54576060dc0439 SHA1: 7c3277c8787b193f3a259a7d29c60fdbaa1f8c7e SHA256: 49624137197cb7f01778930f8be4089dcda9b70521046ffe58c9f0c7e45ba88f SHA512: 5b2caf69f43504e8556a7e80624e9a43501ec958e97e793a075305fff26260bbbbdd5a2cbee71484c06e7c6f097808fdd3b7630398fb53d9b00c5e3ed2f9f5ef 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 1.0.0.9-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16951 Depends: Filename: ./1.0.0.9/libzenohc_1.0.0.9-1_armel.deb Size: 4131592 MD5sum: e1819a7e6ec6e14257c5ca743ffc585c SHA1: d00878db1324288b38189a5afcc01caea0013a16 SHA256: 0d6851183a680ffc4e88732948be286ba583c4ae57786b550a9dcab8954467db SHA512: c262427d3b5eaf4967dc33d777e9d69ab0ffca8f72d5b397346a40a027063b69f8bac732b2cfc7175e2b93e10c5301415a9812764fe711be42a64b2a438ca3f9 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 1.0.0.9-1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16738 Depends: Filename: ./1.0.0.9/libzenohc_1.0.0.9-1_armhf.deb Size: 4166556 MD5sum: ef28b854bd76db5515deef35a8bf1ddd SHA1: d1fb8b3d2511a50ee0487e2063d1a1a26753b0ba SHA256: 3a0282a5923183de5141d3c421a6fc2214a24669ba26faed8144327af3cadfc1 SHA512: ace4faad9da137d117527497df466ada3ee57da5ccb7d1da8d490967dd8a922a6ba2ad57afadac63c4503e44f6dcd6168230d9ad476bd8b0d8fd4d35f8591aae 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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. . ## 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" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: amd64 Version: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 339 Depends: libzenohc (=1.0.0) Filename: ./1.0.0/libzenohc-dev_1.0.0_amd64.deb Size: 45500 MD5sum: 53089d8311c251baf294e565d17b538d SHA1: 790e45ce79ebc48fe6ba935be3b9812d033127e1 SHA256: 384deee279eef39308e2fb119d5b520c42d43255c9e79309429294b794a625e2 SHA512: 256a6bf99a1ee65e14968823186f81dc266d83a2fb4fceeb04d1ec6c8be99da08f4aa814cd13687c64694808c5c7c997e3c17f8bcd99de3746a63ed49229cfbd 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: arm64 Version: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 339 Depends: libzenohc (=1.0.0) Filename: ./1.0.0/libzenohc-dev_1.0.0_arm64.deb Size: 45504 MD5sum: e6821a0db5f7be983c93c523727d53ce SHA1: 63fc549be5d88a0a5338e8e6b2ae12ef7e686612 SHA256: 11a4c054099e48e44d4372706fa96d69c830f729d19be3d76c320569410af0d4 SHA512: 265fd13802e3d2f0091a77ba266c580b046931e6f1050b46f5aa90f722c277396a92ca8cd58d36326c841d27a0c7759da1d2135636229c0d993bdd0f0f73b93d 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armel Version: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 339 Depends: libzenohc (=1.0.0) Filename: ./1.0.0/libzenohc-dev_1.0.0_armel.deb Size: 45496 MD5sum: 343d823560a73947e2ff9d1e2e6a6822 SHA1: bc23d8fdca17582a751247295539ee9f3121a1f8 SHA256: f5204f8ebe60c40c42161a07a0d0332b3d20f679fe5e9490d2a45336333622ca SHA512: 2a5aa00f8a6b676241d8648c7912a327044821c5e13c25fe566429c194983bad8dde075828dae91a89d0c293aa976be1e5b61a79470faf833522ea644b6d5d1c 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc-dev Architecture: armhf Version: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 339 Depends: libzenohc (=1.0.0) Filename: ./1.0.0/libzenohc-dev_1.0.0_armhf.deb Size: 45496 MD5sum: deef5dfe89364931a961250b378fc8a9 SHA1: 977391d6bd4675abec65b3ada200511fdd2be724 SHA256: 83b68a7b27c049eee8efdf42818c51c0420df9246d330d1ce07327ee22098645 SHA512: ce9ecb6c120cc0847f8dd3c7f95ab43a809f603cff0694ed8eb332b6423a3784960ee2421f595fcf04fd61109af4ac93c8254508833d8d11f527856f4809c03b 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: amd64 Version: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17353 Depends: libc6 (>= 2.29) Filename: ./1.0.0/libzenohc_1.0.0_amd64.deb Size: 4261088 MD5sum: d82a2d5ba963c544736543ad7a2f738a SHA1: 4006604417b79d2be725046b350cbd5fb913dc0e SHA256: 24238799a5f43fb404816166accee86eedbf7398ce6818dc6ac2bec9abfc0ffe SHA512: b0641a67b037915af257bcc5338c7c8ad38e9ce5ffc6f9f3b3b08565dd1773c3acb1b0510e0729dc2c08e9238f5c59ef96bc498e9284090015196b68d9d86d04 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: arm64 Version: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15786 Depends: Filename: ./1.0.0/libzenohc_1.0.0_arm64.deb Size: 3843292 MD5sum: bf0f0f8d27bb2ff8f3915ef01eeae1e0 SHA1: ffe231a2dce63e7ff8a7f062908cbd3d4ae15ac7 SHA256: 5ec838706ce56176cf23fe69ca8a2a292bac787b198d04124e8bd989627ae78c SHA512: a555e431074b651fe3c229f2ac0f9ec44a3ed0c3cf1da53f42665ad6b99ccf233b9e50af0f7efb50bbb52200239a944398be572bfdd95b08f5af7fd6173de57e 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armel Version: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16931 Depends: Filename: ./1.0.0/libzenohc_1.0.0_armel.deb Size: 4125188 MD5sum: a33f57a4f2ecb67b466504d85fb78c7f SHA1: 308885e8cdb4f58cae06a273ebca261044c3a88b SHA256: 0020512543a1064851fef6ce9241622512989be1a673cb2b0591f26248e81bea SHA512: b22056879791daee132d6e803ccc0b4d94261112b302efb3f540d32121afe64f9020508be7e810360c000afac68e65e25c99f44fe21f74cf4234fa531571d088 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-c Vcs-Git: https://github.com/eclipse-zenoh/zenoh-c Package: libzenohc Architecture: armhf Version: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16716 Depends: Filename: ./1.0.0/libzenohc_1.0.0_armhf.deb Size: 4163828 MD5sum: 19aa5b2d4adafedd2c206bac363395bf SHA1: 8ec2baccdd1770752eea2772b61d715faf5d12b6 SHA256: 6ee26ed6365d8e1da72fc24e186f9486dd122ebd83967e6b1d22930a6ee2dbad SHA512: 95ae022b1c39ea33436592e4a41f46738e5d7dd72a5d2746a00c234e24ec7b0cb6198df97557a9bff68eefd71ee4fe0b8b91b21f7830d01e98402c5b5aea0c9c 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 . ``` . Unstable api and/or shared memory support can be enabled by setting repectively `ZENOHC_BUILD_WITH_UNSTABLE_API` and `ZENOHC_BUILD_WITH_SHARED_MEMORY` Cmake flags to `true` during configuration step. . ```bash cmake -DZENOHC_BUILD_WITH_UNSTABLE_API=true -DZENOHC_BUILD_WITH_SHARED_MEMORY=true ../zenoh-c cmake --build . --config Release ``` . [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 built and installed. Set `BUILD_SHARED_LIBS` variable to false to build and install static library: . ```bash cmake ../zenoh-c -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=FALSE 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 `BUILD_SHARED_LIBS` . For `Debug` configuration 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 ``` . ## Documentation Zenoh-c API documentation is available on [Read the Docs](https://zenoh-c.readthedocs.io/en/latest/index.html). . It can be built manually by performing the following steps: . ```bash cd docs doxygen sphinx-build -b html . _build/html ``` . ## 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 [Cargo.toml](./Cargo.toml) ```bash cmake ../zenoh-c -DZENOHC_CARGO_FLAGS="--no-default-features;--features=transport_tcp,transport_udp" ``` . ## Versioning . Being a CMake project, zenoh-c is limited to the `MAJOR.MINOR.PATCH.TWEAK` version scheme [inherent to CMake](https://gitlab.kitware.com/cmake/cmake/-/issues/16716). However, zenoh-c also incorporates a Cargo package which cannot be versionned with the `MAJOR.MINOR.PATCH.TWEAK` version scheme (not SemVer compatible). Hence zenoh-c uses a one-to-one mapping between CMake versions and SemVer versions: . | CMake version | SemVer equivalent | Meaning | |-------------------------|-------------------|----------------------| | `1.2.3` | `1.2.3` | Release version | | `1.2.3.0` | `1.2.3-dev` | Developement version | | `1.2.3.x if x >= 1` | `1.2.3-pre.x` | Pre-release version | 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20839 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-filesystem_1.0.0_amd64.deb Size: 4601092 MD5sum: 830886eadf6f687ff656ba5427919f9c SHA1: bfeef20a6694f8c98c651b1e1733dc2406bed716 SHA256: 326fd31c21cb19d9429a755743dc73c228dd7f5846e5e6b09c09044d09bb46ef SHA512: 53e3ac515a4e647820f8919f714c64c39bd2d7adcdeaf21bb06c92f7f64b055cc89434e2c722f6beba67625a296a18af232f82cbeceddf5e73b3fce470d90572 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18942 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-filesystem_1.0.0_arm64.deb Size: 4140432 MD5sum: e98f9a0da97971c94a0eb6e5c9bc4fb0 SHA1: 54cce93bf572e0bdded7615d8bc4943b2372f820 SHA256: e07e7417b41de4b1e815a71c41657e44bffa2a328505f4f45b0c0a2852da5009 SHA512: ac8736c3244c91e226a1536abdeeb36632426fc5ca14e27da0a75886413081d5c428d54024f88061e8a63fcae53b95c8ded027a24db51d10f6c0264b70bbb9cd 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16510 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-filesystem_1.0.0_armel.deb Size: 3909780 MD5sum: 65267bc03da184ab0dc6d080b620bd43 SHA1: bc12cc39ffafea576aed663349e8c162e75212fc SHA256: d02eb2f9dc309ee87a39d12b37c863b7a21c9da14aad44202c4a22a65e2de02b SHA512: 2d7ead8b59d4e59e8199476ab28c2ba0102bb655640d04ea8b09400ea6b4d6ded0ef7dcc81004930cf6952527f607a3674e6848f126e0650d5d6973042f14707 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14625 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-filesystem_1.0.0_armhf.deb Size: 4008624 MD5sum: e0a0e02fa8fc49462b8888337916aafe SHA1: aec19a202c9305e8eee246f77be39e81848e1dcb SHA256: 436037a173c90f81bb94a9a99b0b7c990367c60dd58d2d465e0d9b691b52d6a8 SHA512: 5c97ec2826633b482110bc08e162e8bacd346c330405751ea500c774e6302cdcb1444b28bddeded754c7157ccdcd0d109ae372e5297adf08e9c9c0e29e6de673 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15711 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-influxdb-v1_1.0.0_amd64.deb Size: 3130204 MD5sum: 7695b0c8c92e5cde0bc35e86174b6f51 SHA1: 1e98f591ac306f726a511300aa5b3a74687ce5c0 SHA256: 98476589af8f003805df5817745ab7e3bf978d5d134606602f1002df52fa51f7 SHA512: b5743b872b26e018dfb7c9c2c89c9ec9c884429359c8ab12aa589c34cda3ac0df5d370ace2fe9586f7c03945a2556c69e5efc40cc255d73479c58148e80cd8ae 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14025 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-influxdb-v1_1.0.0_arm64.deb Size: 2810972 MD5sum: ac5ad6cd43f5dde7349349b7c9e1cdad SHA1: 775f45320103e4883cbeffd86d3bea443476f472 SHA256: 101486f4bee10269d56d185453ac8847caf91992bb559ec9b884f416d9fec2f4 SHA512: a2783e77c89b4cd0cd7147efb0be07b77acb15257b716efea42a622643e44346f4549e5478fad053679c36eefadc18cc285b68a6d952f5d24e9b70f693b9adb2 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11805 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-influxdb-v1_1.0.0_armel.deb Size: 2553352 MD5sum: 74edaee289984f1d29b1c115407fb6a5 SHA1: f3a33ebe1cd10b00ca7a1d654edb6ad03823e1b4 SHA256: 61a20a356a694990d4d8d9e12f3fec650551c69c3adc8e218686e9724f976af6 SHA512: 9e26bd9219bbd46977e6e84d7384846e0429f726026c0694d272023adc419097af3b85110b2ddfbf3c9508b94025ecb9f1d9f7932e347a72d5b8bf7b833ccf7e 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11678 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-influxdb-v1_1.0.0_armhf.deb Size: 2545040 MD5sum: 958d2974ceb646863be0dd7592ddb0fb SHA1: 7dcdc1cdca70f6cd1799a8ad51108cc5616d137b SHA256: fac596ee192d7ce254373eadf35f51eb1e0e531bd34f5a9d711518420bb2ac88 SHA512: 4467b3130e2e31202523f562e4e1e48c8492b68534d5c90516629380ecf2835d968642ad2ef9d931f031199b75baf178b4836ee06051d406af2b3440decbd948 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17302 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-influxdb-v2_1.0.0_amd64.deb Size: 3805020 MD5sum: 8631b5b3e590e52f1bc0bc2dd5f9cf98 SHA1: 00a92a3fe0cc666011bc3cc7ac1cbdd836966de1 SHA256: cb7476cbb7d6fda7692ff5cae23beef91d33e5d532db7a72582927e9c3f81e75 SHA512: 7c5d60935c3fd834d70c803270f16bf3eb7c12737e27fadb870c01de9ee05b30c2ede3c529aa75646be775848ae9ed0fba20241d6323506d3b409340d1486a4d 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16281 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-influxdb-v2_1.0.0_arm64.deb Size: 3487404 MD5sum: a45b6d30f1257a682f4bab317c8bbeb2 SHA1: 4ea927307ca1564219f8eda0741caa6e118481e9 SHA256: 6da23353b8ba273c22ca7bf3b066e5fccaf839ca92c822f2f35321eeef0e1458 SHA512: 34dc9455dcb3eb623455f8cf06b8a442ab7a186e3f26ba71de8ce5b7382bfdbbafd030021b74519c6a59a5ebf652a7173aea792a52887d5e182a59a574e7e73c 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15591 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-influxdb-v2_1.0.0_armel.deb Size: 3470264 MD5sum: b8274d5b95d156d8ba78db02d114601c SHA1: 9f22621379d3293818db5f00f443e595b586d9fb SHA256: aa07feba4b318117d02ea35f3da926c019cdc8b527f71b776017b40b2c7c707b SHA512: b28ae65b03dff67dd9347fbf15a640b6d7a305842fea9be2a376085947ee9ba0ab2b1879a0fc7d47aec3e5128383dc1e8ac27bfd89ae9383395942671b66ef2e 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15489 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-influxdb-v2_1.0.0_armhf.deb Size: 3512248 MD5sum: 5ced580da6df37ea39ae9f3968227314 SHA1: f10a4edcf01536e456c28fa33687d69c138b083a SHA256: cc35b5a0b7c30900ce2cadd042430da945ab7e708989b2f24bcd912a2e7df121 SHA512: 8f2fc6d2b22d334383ed3c33f50048fb91ecfca5f6a8ad00328898046587e3f6008b9e79c762630fd9ca604fc0566ded8b73cbed5d51113e3b9594d0eeffcfb8 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19383 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-rocksdb_1.0.0_amd64.deb Size: 4330572 MD5sum: 1d19d7e02d7dfa126321ab0e750807e0 SHA1: 1afb0a71d18c622093d1f39f7ff35f9cebf43dca SHA256: c6c5f448dc28ecc4ca74f1db9fb28432a0f176669bf4bb87ea488df71bcf816d SHA512: 4b953c611de669a2aba3c77ce76810f2fd1628ffd2a48b66583520de73d39f00ba376207134e2efa037d8e228fea969b759b3241650b264538b8d6592a11810c 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17484 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-rocksdb_1.0.0_arm64.deb Size: 3890396 MD5sum: f434966157bd2e4d84d7f890183ee8b2 SHA1: 801fe1ebead25478f71568db955992ecc603cd4f SHA256: d854cfdaecfd34f871b2329e2241099b942bb4ba71d2fc2f7db044eaa090f50a SHA512: 05b1f02082848668780fa659f7a9bde420e88dafc06fb24f52ea8631fc8265f956eb84ef1b96f1053dbb559b45a04c6cd9a709055534acc828e70a10b3a1edd0 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15303 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-rocksdb_1.0.0_armel.deb Size: 3699308 MD5sum: c8bd999abe0fa92bd983f5f4c254ab3f SHA1: 96103994fa5138eb12ffa0b06714a811cd3d167e SHA256: cdb38e037c78af0036a1b1e57a0a18d0dd6ab247f3b301295d0526083258f935 SHA512: 3eac81915f7bf010bd315d43279868b57261a7e51f48133568798641ebd83216e8b0fcae3a636941d14b1f5b4f77a949280857deb0815717d7acb91b7e9dc880 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13400 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-rocksdb_1.0.0_armhf.deb Size: 3797772 MD5sum: b9a40f7da212b830f490f6063adb6bd1 SHA1: 993a85f7205bcbbe1ad1a8250954a88064ad1067 SHA256: 5e5cba14e17e40d32db927ae3783081336b04c047631fd72e4bef34d22552404 SHA512: 31148fdbb2507eed6fdb4eaac5b46200023b91dbd41ac720dbdf7d7bac56ca9672754bb13038d3a2a0ab00862549ddb298ac2a6e39da8376faa40583bd1e9c8b 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27262 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-s3_1.0.0_amd64.deb Size: 5515264 MD5sum: 31ecb48ba76df1ca8e0baf44208d8e44 SHA1: b10b79633202a7fae1b6c5e15cf9630ccccc352b SHA256: 20b100b57abda35a9cfd831e9f6e09f49f140ef9e270beff7335911c8af69631 SHA512: 5f308a5e10dbffe2c0fd165a743451c724be15f3cc88556c4a55a6f28679e2cb121db6bdbb2ed4423fb8335475cf46c4df344339c50c407b0946dd488b38fb90 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26511 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-s3_1.0.0_arm64.deb Size: 5230444 MD5sum: c2cc371b89d6c1b5db68048d90056baa SHA1: eb64baeb8419db994842c6ad8d9cefe1b8b79942 SHA256: e3819a3ee07fafd4425ecdb3169f84a3458498f89c12a208284f67e3f4036626 SHA512: f4057c981a6964f1c13637ffb07b15d7ad1a0bdb930287976c68ed49efb9cb2a10776ee4cbdc79431bcb51c5b6ced76755752a30e5c4695e046aa087579849e1 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25178 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-s3_1.0.0_armel.deb Size: 5088220 MD5sum: 609a677cf028d54101b2aec311d73cc0 SHA1: b03c3719810176ff4204d7eaaeb10c47428555a2 SHA256: b0639feff13f1b195b84267b69350445c06c98d64f417539ea440c84c8354388 SHA512: fb45581e33e3023a81a5ccafff09cfb70605407e8976f19c89bc614f26d502de253d5074927be31fce79ac04ac16ee9165d21f436160053e630e0dbb6c3264ef 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24943 Depends: zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh-backend-s3_1.0.0_armhf.deb Size: 5131728 MD5sum: 5bd80dd362471958039d7ceb5862d610 SHA1: 77d316f8d35c48f9fed2705f5e7ec0f100299fce SHA256: bf0fd84d1177f74ecc73187526c5f6f37378ebfc2a3409d64ef8c0a47c74054a SHA512: acb00665992c6d91039fb47fcb5d62c8b77c9a9d907314489741de92e27a920a9add1cc7ac4e21ebc7fb4197bdd3d67c7a90880d78b6c4813c9bf63c791c2a2b 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20592 Depends: libc6 (>= 2.29) Filename: ./1.0.0/zenoh-bridge-dds_1.0.0_amd64.deb Size: 5276160 MD5sum: 2879d642bdb00f155c1b7bbd48f8fe71 SHA1: 9424251524be190cfa5282421e0b06c4affd2785 SHA256: 3b33c453c673595510e216ac4021e041bc71f3d4f3b33c95695dfccf794352cd SHA512: 937a743754d24d39e6c8b48f6d994fa4cd4e04987a4425fe12e61ddf3027b96d60f85d41c25a23f5152ad71418fdfba812ad0a40bda39d987e6091d5d95d1862 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18820 Depends: Filename: ./1.0.0/zenoh-bridge-dds_1.0.0_arm64.deb Size: 4772700 MD5sum: 30a2fc982b484b30e0c4e0a026bf96e8 SHA1: 5f47ed3d62ab7404f2c0bc618fb59aeb6175ff53 SHA256: 506c43bbbf7a43f62a39a1b71755e3fee8753ee557ff91e39d99784e37a4fa58 SHA512: 19cf6fe5263f0ed8943eaeefc962022b436488c509775e1ce62b6dbca2b5c488c39ea856e9a880030d094d660c2037c3f8f90310de68e1001f66651db5abe96e 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19959 Depends: Filename: ./1.0.0/zenoh-bridge-dds_1.0.0_armel.deb Size: 5035692 MD5sum: 1a944dc07890df50edc781194f89d384 SHA1: 60c29f27833960d09b322eb1056f024aafc89bbc SHA256: 844809c9fd18ceeefaec694b097a6cbb0cd5694633eae31f442c285f578a48d4 SHA512: 2b5c50c9863273091479b87016508b9fb1eb3724b0e16059dcd49f4e55cbed68f48a289f153deed551b6fc5e51fbc8318b62b16f6f7383f30da63f5e784cdefa 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19446 Depends: Filename: ./1.0.0/zenoh-bridge-dds_1.0.0_armhf.deb Size: 5090340 MD5sum: 3d9f392b8b76ceff6380844d09dafacd SHA1: 4ed2a31d8d8b899200c03cc9e8b587044950099c SHA256: cbb79c792d50c9c4e8add889214161cca89aec9b479d9c6ee3038e0ef6f13c77 SHA512: 1de3f1145a513de7f095d7a93d85b2d4ca1c59ba5406efa7431a3185a438386efb92fc45fff0a0ca06fec6530d0e03967c3a9c9155aa1b112bf92806759aa3fa 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20519 Depends: libc6 (>= 2.29) Filename: ./1.0.0/zenoh-bridge-mqtt_1.0.0_amd64.deb Size: 4950716 MD5sum: 0502e4dba081fb0114939c435bce0f9a SHA1: 8d643f8737ad4099a494d3660f183156058904af SHA256: 614eb19f057ad474e65b29459ee50d0599031f09cd309b5d13d222d8e705ee6f SHA512: 88bf984e6ac8896c2a44c9370472c2b37ff71aeff2df6bfc1e0b7c617a735f070703c1818ee435a3da0bbec425ce941f344c3a7b44d8ff9e42401281adfd623d 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18739 Depends: Filename: ./1.0.0/zenoh-bridge-mqtt_1.0.0_arm64.deb Size: 4481376 MD5sum: aa8ea1e6e9d1f99b5a1b415f5f6582e7 SHA1: b1914edd8689ea2b81760a123cfa2a420d8457e2 SHA256: 91f3a551cd96a0ff94f3cd827c60c3bc2c481fc6f06d5a7b5e989db35e93ed1f SHA512: bab801060631bf5161286bdbd432085ff79c6e852ff2b7439bc337abec8089897d3f0cad22be320379399e8cb515d588ebd904317badd439e33e8badb4b33777 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20041 Depends: Filename: ./1.0.0/zenoh-bridge-mqtt_1.0.0_armel.deb Size: 4761336 MD5sum: e3f4aa7ae1082bdecf236a90e00914e2 SHA1: 1c53d61ea2e1906d684a2b81761186ec3a43348e SHA256: 1acd00f6cedb5df536ccbd972c42585d040ca5b6ed133a743734ab8d70fff564 SHA512: 49c580036c6ed213365b38d8603589ce679deda24c16808aa5f37602f73ea88bf1d24fbba03457b07c28297048d96625757902f6cadb5dd7bd3ba8b222c5e42a 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19771 Depends: Filename: ./1.0.0/zenoh-bridge-mqtt_1.0.0_armhf.deb Size: 4796304 MD5sum: 48a939d0cb57a55c3a252521bfb8f281 SHA1: e3cc8fdcfe48de7de35b54d02d3359260e2d027e SHA256: 9746b4c416337f478375de30918c35993e5c427c5a0b08e5c125ef4fbc999e82 SHA512: c88c354d6fcbaee31024f97d11ccc5fa9e85227e522985cca92e65f5222eb8d07533812c0f88d83820a5beebcab2c4891166aa2865eb76b4e47487ba7a3270da 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-ros2dds Architecture: amd64 Version: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21149 Depends: libc6 (>= 2.29) Filename: ./1.0.0/zenoh-bridge-ros2dds_1.0.0_amd64.deb Size: 5378296 MD5sum: b536f6800f6505af1ace18d9ff7a166b SHA1: ce5f7893cb23abfc87c0e1a997722c924590d6cc SHA256: bc9202cdb104e0b16b97f30b75391a9c4f65996fd08522c5f1848d267fdb6ad9 SHA512: 8dd7d66edb8c78389092858b7b061ebfc9924f0693ce75b80467c8c73307b0fc4fa440776aeac8cff2348e9a96f81d277f34c32342d64e92aaf60328fe64ba17 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19355 Depends: Filename: ./1.0.0/zenoh-bridge-ros2dds_1.0.0_arm64.deb Size: 4882452 MD5sum: 3f1b51d98338bd2305cfffd77d8800a2 SHA1: 472836942e7d4256cf7dc2b7f2de348982ca1803 SHA256: 989d76e41becff6dc2aa7367ae12431843b5a19d92723f7278dc3312aa3ec4de SHA512: bb0f766e50a6a8e2a2b307aa12f60f9292ab2ed7b39ac7266aa2bfa911df685ce128e71c861f35593a9e37a0342fb970257dcd1d52ecd10cde04996d3f18bfac 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20490 Depends: Filename: ./1.0.0/zenoh-bridge-ros2dds_1.0.0_armel.deb Size: 5143180 MD5sum: 19f3fb6ac0fb561c33107eef54042713 SHA1: 2b2d4297b74693fb6f08dd9ca1b7a566b845bffc SHA256: 5fd848aa6d3896f47b3cd8e4c7444f4134e19efc247e1df786770d1acd261dee SHA512: 89a6bca79cd8ae05e8cf29a6bc6315a86019dec5ff161915694d6c5b346f74d922c259552cd3550b5f0cc642a23e7d61997ceafc3671e3e339a4815ac44157f6 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19983 Depends: Filename: ./1.0.0/zenoh-bridge-ros2dds_1.0.0_armhf.deb Size: 5202224 MD5sum: ff93ec0f6498b0fcb6137ef0dd074249 SHA1: 6de90c5b85fe01ab685337e57e4e08cbf8efcdac SHA256: dbd0457ab54c89ac2fcb6da72d3b4b4103748242df77a540c5e98a5b57d63b25 SHA512: 3cb17fc3219507fe5708265592943fe5cb1d2b91e50e63c90537012bbfe022ed16b5044508162b65d7181e4102cada7443dbd71b6263947cc8cbd25fa4dc2020 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12750 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-dds_1.0.0_amd64.deb Size: 2570824 MD5sum: f0afa72d0abc56744bc1ae2f87c1f130 SHA1: 3b1ba02806b11167d7b52c4adef407979dad3703 SHA256: 8d32212064ab255b06137135cf7858b5d4307fe052abf56139fb9c5c04e63015 SHA512: 9705b527c36ae3f15b5720bc796901587c7aedf0617b6e1d77c9b353434fda0cc6c8e901d6f697c345529ae8482208e44e9b0b35196b48c151048f4c42e73f99 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11561 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-dds_1.0.0_arm64.deb Size: 2337168 MD5sum: cc581cca549c57f2c3f26ceb65bfff9d SHA1: 1410de83fe6f86564af28924d3ccc265bf031492 SHA256: f56985c1e836ad9cbb452afeebdaa7ee36833331823b561b3d7e5a060d769620 SHA512: 7f8913b93431e6d07cdeab792e9e5ee6434a10eb425ac3edcdc71120d82c71cf5f8f640965fa5ec84fd25586bf0fa1be58676b66da805778a917942d1f395585 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9584 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-dds_1.0.0_armel.deb Size: 2182260 MD5sum: 76c205669201ec62ce4f20c1a216ebf7 SHA1: f05aac9791f245eeef0577df4d41d1d497967ba2 SHA256: 30521c7ffc46c05cdac864b90950dfa3a3bd78d815d9759ca2736bd9e8aa30c2 SHA512: cc075374f993333953ef2d41a95ef22cb7dcde358f2321d80f4622fe85222f6940dd43abab10836bc3046c7693c70d2760cc3a315c8a5987dbd524b73066fa26 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9207 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-dds_1.0.0_armhf.deb Size: 2189612 MD5sum: 5f8e8d0f341a2eea4ed237fe2ba18022 SHA1: 87f1974ad23825d7cb23289e72d80d624cab9092 SHA256: 3ae280e6982981a3a28bfdc5c40a6c11447999d7e34015eb9362a9221a2dcb99 SHA512: de7723d304f8e9b128f136b7d5861c5dbae9aa773171f140c4fc2bd7ba5bc197655a8195e130a480910df162feb5ed8dfbdfb1bbe7694665376ae20fd88bbd70 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14031 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-mqtt_1.0.0_amd64.deb Size: 2871496 MD5sum: 5c0d1a4a79b6cc1cbfd068fdc0f02e7b SHA1: 2e8d564ab1f50171dd307a5fa0028299769415f0 SHA256: 95e5a64ed0c87cf7d331e0ac4c45b66f4e3ab0323677a17d9171d5b7a7910844 SHA512: 37ed5550405ce1640b1690400d0aa66c904da58a24eb437913f304ad68ab3ae421d5ff352b4a771a6d7faf7bace6d36d00a0bff7c37fa3575095065410605458 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12756 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-mqtt_1.0.0_arm64.deb Size: 2565284 MD5sum: 69e83f4c24a5d87388e2bddb07a48e1c SHA1: dc9429c2247801dad45ed371c92d42d467ed2440 SHA256: 7cedd4b7167b16292c32cc0c0d5073bf4559f7b2f919373684496f69968c21a5 SHA512: 0a2f32e47bd175b703aff2cd827fe855ff2bf2cfc163049d33b6d6f185ce18497ed378a1729bdd91b059a7700840c125940133f2d6813b8d1d1588ce5d677209 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12756 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-mqtt_1.0.0_armel.deb Size: 2636292 MD5sum: a680a585706e22928a616c3b8bde5053 SHA1: 8091bbb9a239d5e4eee1f936474e00ad148148b9 SHA256: de0e6546b001042c4c1bc832d383e5e61b7413e95321a5b8d5ddd3ed1cbf6441 SHA512: b69aeaa3f9dc13b538f1240dcba3abe0e55f3901460a2e0676cf80be227e8bb9c6f2f79cabde26e623933468c40f1e68092cd194592a0aaef132540d4f8fb555 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12672 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-mqtt_1.0.0_armhf.deb Size: 2678552 MD5sum: 7298838eeace962297e89192fc4aceff SHA1: 8d8925a8013038ac0417a576696e0888b30c197c SHA256: 80dc1316a28f30de286557265cc3bc2f3291bc3e466a4c6fd2a30f505a5bde7c SHA512: 2eedfb9ffb28b890a98df0bc7dd35de4c3307a90f01959b9a6c484ecac996bc0b8d646322e2b201f179426d15d0acd929c8cca28d9c7f1938e622098d2666516 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-rest Architecture: amd64 Version: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10854 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-rest_1.0.0_amd64.deb Size: 2086460 MD5sum: f9e92ee96a81e4c1b884d3a3092cb252 SHA1: 618aa62692b87668cb01b1ccb9f1241df7a6ffd5 SHA256: c1e6d53024a7f5ca9646e78c5ea86b20882a5691385822a69bc1b97de4f29718 SHA512: 51c4947fbb54cee3b0c8a1f6275400c933ed2352f7eeee89ca5ba5a99a493f3ef4a7526ae7439bf580f5f51d86e4a9d188f68886250f3b3eed38f8dc4c772c01 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9831 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-rest_1.0.0_arm64.deb Size: 1909860 MD5sum: e1d8354ff9d6c86f303779af14ad8349 SHA1: d53d61c66e4a2ff47ccb339dadb4e8863dd62527 SHA256: 8ed611f7673a5830d03d41ed7f069f2ba2b98a57107b35ef3c96981c7340727b SHA512: 2633925d5beca44e2427742c38fa0f5da58190d29e3a3e929a6804f86ca6c709b7a7422b0aabadd823ebb9fe0ecc73bf4c651dc8c4e0e5be99884f4bf0039a45 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7981 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-rest_1.0.0_armel.deb Size: 1780572 MD5sum: 214fa66616d68b16f410cdc8c5ba9bc4 SHA1: e6573823c3cfe40c96c1959db767ad006d768218 SHA256: e56074ff5e67c0f6ba1d2ecde132ca771a364c47d232e57599d80f9297403a31 SHA512: 78296b5a811a4f8f321f58a65db9fc36943dfd0d95a70e692aa5f00023b8c7ff99d44bc85bdeeb2bb082b39b6570cc2e57bedaed2dbaf726753a91561770ccec 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7887 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-rest_1.0.0_armhf.deb Size: 1770108 MD5sum: 079d21578cc14de1008f4857c9de1680 SHA1: ae863eb9dbf5310f1ae30fe667d177bf48906418 SHA256: 3a800e6b192ce97f249415408cd4a4b9136247e61cbb54991e4ecfdcf67c543c SHA512: 408ccb7b549ffd3e8af0f6a5a644487f463557f4b626d06218dcb0c83e324e76f866734266650353c5b9d862c8a64811a3b9e72b97ee64bb4a9c0b6abba3bb06 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-ros2dds Architecture: amd64 Version: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13291 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-ros2dds_1.0.0_amd64.deb Size: 2662836 MD5sum: 5bd71c5fccb837ecf52ce2751eac3a01 SHA1: 474906332b17de2023cfa2cf5729b2ef718f398c SHA256: 09484bc7a0f656efb1d126ee8fd8499e56699db0dfcf2b4d03478bcd0ea8224d SHA512: b7efdf3372aea1a0537e9c7de02d19813490a3ea22db673e06b9489d2e89be5dc480af75557565e2ef9ba4d033f30583cd5718587f9d29960f760bd72225ce3b 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12069 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-ros2dds_1.0.0_arm64.deb Size: 2427624 MD5sum: 18afa3f38df091e46fd364260e7fbe9c SHA1: 02a8b3fb07a5283bf455c7080fe1722d0ede6c4d SHA256: 25356518fa9c1504ffb12369131107b7c68fd945c3f9b06e91524000617cb23b SHA512: 91c46993de201f44320bd3db1bc68737f143faae793c2e89b73a77058d3ade503442f5dd37fd78fa07f320169fec2fc78c618355bd494d4d556a59de15db210e 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10098 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-ros2dds_1.0.0_armel.deb Size: 2284444 MD5sum: 195d7d9c938356445caa0b1126199bdf SHA1: 06ec542ba02a21632ad731b6144249404afc368a SHA256: 83663dfb4995543c9cb4103de0afc02569c93e7d30507deca1bb3fd1fffedb7e SHA512: f052c0af56b9a7952d2922082c94534187650b4446cd8cfae3f297d7d9a5afcbaf0b40c27dc0698ab87665da3705ee09d921acb851ac1c57304f94aa5b592cea 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9720 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-ros2dds_1.0.0_armhf.deb Size: 2292620 MD5sum: cca8e64c1c112882d4823c26e5b3d699 SHA1: d4595b293b6bc4aad08bcf02bc3cd9199487955e SHA256: 811513afce942c5fa03518239ac5e277585a26ba50ac3018db0ea138d3a92f7f SHA512: 9ff8dfd94fb1a47e4697a3aded9c8f6b400beca4b4daf731b359c6f26c4a05b618c2a22d11b7fcff85ce29fcc292df39ecaa299c367bc0cb14f28e8d97a975c4 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10583 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-storage-manager_1.0.0_amd64.deb Size: 1977364 MD5sum: 6ea3c8b892e27e6ec12d3654dffbc06d SHA1: d51402626473403d4114f4ce939e66851d168260 SHA256: 3d0967672399e9d3b1539eda756be800c00bf7a69e3b6f4aa14c5bf3886ead28 SHA512: 11d79dfae5c637679830b79ea1804f3120dd8f4df20e639af39d9bcfdd33ef4748873d588494b05e176be3a3514636bbb8a5a6197722cdc6363b302e37b3e80d 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9551 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-storage-manager_1.0.0_arm64.deb Size: 1803368 MD5sum: 369dadf7f9cd0268dbe76ccc06348611 SHA1: 996abca9759ad437eca60d6e766c0b8ec338c531 SHA256: f9497bbaaf03ebd63f976f2ee5b5b5a6ee5c75bbc04036b97a858388a586a45f SHA512: 744abf7e893d6c7afe742a04a092fdcf37cd00b6a434c4343cfbb00de3146f7f4eaf65107717eb6ea1e84772abb0022a003bf95686068c5373c02c04e6c32ba7 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7735 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-storage-manager_1.0.0_armel.deb Size: 1698604 MD5sum: f5e8a5522a7f0b897ec1e773c0bb2276 SHA1: 55b7032fdee544dee3932075cda705667592b7e1 SHA256: 3b475d75941eb16f0d2c0cf75293615b25e4311c85089c725314a2fce154a4b4 SHA512: d67d9cd1eaf53e0b9a74932347b23a40428e235202c2534a9d71aa29a46ae03634334da8e2f8f8197abe74e8fbc1e89a56c8d378b5d0dc6c0317b19a1d9fa100 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7620 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-storage-manager_1.0.0_armhf.deb Size: 1683192 MD5sum: bb7193269e37e53ad55da972834373aa SHA1: 540170427f701c70464480543fbf3d58495d0ce4 SHA256: 4170a9b7ed25c2d1e0ac9897cdb66d752842739259bab395b0b3f5c86137b3f9 SHA512: 6ab6ad31e91a35289ac09c604a21ae07c92d935f452df9f4b4825888b4128f586157ee71a5f830fc8c584494b05bc533df9bda02266c0fa125a0b1f92b7421ea 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13313 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-webserver_1.0.0_amd64.deb Size: 2517992 MD5sum: ed242ef0e3c6d3f2db5c25632d2f5371 SHA1: 9d942fbae983da25312164cd60a540605abf278b SHA256: 16d5ca088469b4ec7925194e87b1d2bfebbc4fdba547d2d7059f8d7fd2c6cdaa SHA512: 7f2f75979bcbc985d8a7ef2ded2bd2cd94e17319ba14994734d8ad4964b180f5950baaea9711d2b6bfe53ca9c48b5b86aaf675c79ec5b213bbb87d88c03125ad 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12501 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-webserver_1.0.0_arm64.deb Size: 2352652 MD5sum: f6f15a119a7152b4fd7b72ec45c9d020 SHA1: 5000517952ad36329d758cd3d98fbcc2e85ee8ed SHA256: 570381dfb44bf6eab2dc203800d210080fbb00792248e4ee38a396b9e52b9243 SHA512: 62c0e33a9929d7708ba0380b343fd4a73ab842a21fc966c8581646c323ad113fdbe3223f071698e61fd4e25461a4111749cf39815c9c74f6ef652fca7b2d9ecd 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10192 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-webserver_1.0.0_armel.deb Size: 2144928 MD5sum: bc585ec201cbeba7fcf9bbd245b59ff3 SHA1: 5ae5a5e51f57a953edf403f0c1c8926f6284280c SHA256: 7a9ac9d371d7260534a0561f72416bf82c86827c8cd74f7819aa73fa5aaafc2f SHA512: b6689e13057d98675a2afe02a304a415fac729b75b6a9b09eddd8cbffa0c07fb3542f6391fbeb839753d36d8f83cd011f2188d540a924cf2dbb423340411d2da 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10063 Depends: zenohd (=1.0.0) Filename: ./1.0.0/zenoh-plugin-webserver_1.0.0_armhf.deb Size: 2130632 MD5sum: 07d726ca28f2911ad78480583996785a SHA1: ea3231338c656273bc61110fc177bf8854fc1e48 SHA256: 0dd9c7af08b50a656a0d093d13c8a207830871165721aa7b53ba9c45b5a4cccb SHA512: ff6d7f6d9d6a1b74e6924e09eea0f9a13162b97438fa50a024b0ad73930ad5d3f325e98e68b9b49e67d8b54f054e541ee8b8a534ab176470f8e2d268376c0314 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.0), zenohd (=1.0.0), zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh_1.0.0_amd64.deb Size: 17564 MD5sum: 031060dc370354a61a665d5f266e043d SHA1: b325e988cc8f3134221e3b3d415a0ae66b711fd0 SHA256: 88313a48f87b03e641420b4eceddaf26ef50a243894fa90644e74a05d76f2e3e SHA512: 8be066d59a4e8ff6edfbf94c25a13d59cb775abbfec0fb00fecbade0e99643b6dbeb556d56b3281019dbcb6cab2bed94fa9c6939d6e9ef9d9603e6166f269422 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0), zenohd (=1.0.0), zenoh-plugin-rest (=1.0.0) Filename: ./1.0.0/zenoh_1.0.0_arm64.deb Size: 17564 MD5sum: 6e2b0faf1bae2ccf8a8c426d4e89dc94 SHA1: ae00626a0073dd109d7a74be46c558db27541d58 SHA256: 6f30d6fcf5bbadf6a4eb7c70a4013b120ebd16cb8247d44d83405a80c6782bef SHA512: e1c4ebac6201f9308e1d4ca2773ecd3a64c18ef3199c2e7555dfe715335b7b2a9829a3e72267b6439efc645a1c0ffe0d665bbadbd0d04e347cd6aa3380798684 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.0), zenoh-plugin-rest (=1.0.0), zenoh-plugin-storage-manager (=1.0.0) Filename: ./1.0.0/zenoh_1.0.0_armel.deb Size: 17564 MD5sum: bd670175fd45cc88286a8e8dedcac3b9 SHA1: fe440353d62b47f0e413475cab7f53fc027dff2d SHA256: 6ed9ebe42907cde3f6058705c0c9725a0b73ec72ba8b6578f1130607ccaa8e80 SHA512: a7a9fdf33d5b11b27750a48b399a717961c5f2389c8d7726754f7e8483d8400d8f7b4aebed4dbae5487d30c3cce8dd47329e916032208b1db36060d4eda6382e Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.0), zenoh-plugin-rest (=1.0.0), zenohd (=1.0.0) Filename: ./1.0.0/zenoh_1.0.0_armhf.deb Size: 17564 MD5sum: 16560a9fb0bd198a28347d4c3d1f186e SHA1: 214fb803918da445632bba19ea78862158554c83 SHA256: 1fa67efadf3fceca7a0b78f575bf21044e1228a2d1b0a2065f9981e5dbdcecbe SHA512: b4bd9890fee8664e84bb7ffce6d3a0a5966052eeb9fd523c3195b67592c4ec59d488f2ed6840f5fed111772ebf46840013f871a45ebcbc0dbbcd23f240ceceb7 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18058 Depends: libc6 (>= 2.29) Filename: ./1.0.0/zenohd_1.0.0_amd64.deb Size: 4423816 MD5sum: 78df6b3d680b2e773f8fff545d116752 SHA1: 1962c683c1aa5cdb9c92a2d47f0b2ba87dec68cd SHA256: 1778422446caa74247148b42e7b77d0ae8d5267d72fdc0d370bfdcceeb1e0d0c SHA512: d4269e4c7b0039b5940f01764dadc2000b8991b45ebf7aeacd6c006d88ed0b809fc1b9bc6abe7083d0dde8fc21b2b691dec2d1a833a0b41caa403ae4ead7b97c Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16208 Depends: Filename: ./1.0.0/zenohd_1.0.0_arm64.deb Size: 3981280 MD5sum: c198f9b35bc430dbd0e684e2b65a9eb7 SHA1: 0e7f59bd6de4391533c4c65a1fe0744bc7957285 SHA256: ec886169c8ac29662fa65bdce60269f0aa5d5272bf7fb0db484ef7f4ae4b8b9f SHA512: 659ef8b58dd6f6173b3f9bd63b51870c91e9753a402aac89f9ef5ff1f865c145889357e4769df60568c09a5ed5519bbd1b62e45f52374da62bc80c21f3238306 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17556 Depends: Filename: ./1.0.0/zenohd_1.0.0_armel.deb Size: 4328368 MD5sum: 0f9233051cd657fab8627f33aaacb94f SHA1: c6b3e59f16728cb15efee1ef3b7df65f79da937e SHA256: d6c50a104a3cb9d043bace39d412536ccf29a673a0a091e5f1bb84bd4722c222 SHA512: def2d9669e4250deb01a7d701748bee8b23cfe5a61fb2047c1e8c04e3e48b48655b2d64803f0218cc806fd8c33f07780d06b57de8f10c4d86a14b62aff93e7c0 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17344 Depends: Filename: ./1.0.0/zenohd_1.0.0_armhf.deb Size: 4387632 MD5sum: 8bb8cd953a459975b8c285bb81819c26 SHA1: cacea0507cb67689d5826f555d068eea01b697bf SHA256: f03f0e7835ef8b275c161110a139ed4dd9cd471adbba750be1546c719b071cc7 SHA512: 07b2ea2a0b979268b106f0170eb5c61233bdc29222f74d187711cb4583268d271fb81446a6d95951d04019345ac567898e29e00fc8a450eb8581a71e25a75e5a Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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-armv7-dev Architecture: armhf Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 29452 Depends: libzenohc-armv7 (=1.0.1) Filename: ./1.0.1/libzenohc-armv7-dev_1.0.1_armhf.deb Size: 9052372 MD5sum: dc7759330e8440f4fdcae2cede6b5497 SHA1: a4f38661048ed4388cb0e8c5723c7658a821cc2f SHA256: 3cbfc1086324d50b0877c0d920b8d44f5e11860a457c4c857aa7ba0e5fca8282 SHA512: aa9a26eabb2b42db1892b6c2e1ff29d3a31b6a58748e2883074e8611f7c208821e753c032d97c82c1127f17a0a13fb2fc20809e7dce8acbb998a6591a1575066 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17405 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohc-armv7_1.0.1_armhf.deb Size: 6637462 MD5sum: 57ad0e0b8d33b0096bb99dcbd4c2c4f4 SHA1: 97646c84f5ce60e22b468c73ce95b682b326d9dd SHA256: 31e7b26778c4d15c0af777175d7b81028a6112ea295c23682252ee17082e0767 SHA512: 43057a46542500ffddcbb9dfdb24e48ae6be9fda1e24bea9dde3e723ec84388cbdd4a2b8e1c0614c7eb4962c8ffd508188053e1fd037d75f2d6ed3d0a12a240d Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37341 Depends: libzenohc (=1.0.1) Filename: ./1.0.1/libzenohc-dev_1.0.1_amd64.deb Size: 8684812 MD5sum: 93be4156ebc1800157535b4e657d3aff SHA1: 5c5c85d212e61a2957a76689c709f7c849d21b2c SHA256: 0a8ebd70c08524d4880a1abe67152241e773cc77b6c1cadc39b1487ccf52a574 SHA512: 35f2ee2cc3ce81c10897e56c18a286539f65ea5b971a4a2163decdcc1ea3e9d34f01f07959dd1fb097df9c4bdf9b95bdbaefef37358b79075a0bd29af5d24a1b Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37531 Depends: libzenohc (=1.0.1) Filename: ./1.0.1/libzenohc-dev_1.0.1_arm64.deb Size: 8751960 MD5sum: c56b6d49b199788b09bbc960c52cc3f6 SHA1: 032fa9eb76eef55e823ae58a0a12a952c438df87 SHA256: a9dcc828a47c19138785facbbd390c5eb2b9434019eb3323d4d2e3f3e34ccf5a SHA512: 7037f623b7143cc02f9a80be5162ef9f85554fcb09b0afeae097612114229f21414b4c1549d6503648e1dc59504a0fe2937fd19858113f15f5918f1ba4d515bb Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30288 Depends: libzenohc (=1.0.1) Filename: ./1.0.1/libzenohc-dev_1.0.1_armel.deb Size: 9232470 MD5sum: 068dc6bb168c0100fc45b7da65584cfb SHA1: 3f0451b75f7442d59a13c90ef8b4cf64dce7b7ec SHA256: 5463df3a51d4af86bd4bc2a82941a0c103e71de482a59647774bd1e4a2fec6a4 SHA512: ad279ba9e88c26eb34eab9e0b398edf4b0c22116ddbbd62c98e6268f1d1fe60e7c0be5cebfb7a4176784364e3db7ec920a7d9345b9fb65f70621c5787a5be8c7 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30448 Depends: libzenohc (=1.0.1) Filename: ./1.0.1/libzenohc-dev_1.0.1_armhf.deb Size: 9332948 MD5sum: 04a1144d366e10e9ba236ab1690768a3 SHA1: 08b2fcd7fbd3222403279761b72f70dfbf8abfd8 SHA256: 90c4f17866658a7be09b67c6aadb8dc36691189dd8c2c7e120ea0435d6dbf940 SHA512: 63a9d9dce69741fd0cc57ccac4b355310271a8c4493b08a407189edb22cdce3832ee57e9ce61a4440fe07c14fa7b50b37167875899eb139c789ef28e0b5cc393 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 33215 Depends: libzenohc-musl (=1.0.1) Filename: ./1.0.1/libzenohc-musl-dev_1.0.1_amd64.deb Size: 8444374 MD5sum: 2e2ebba538cfa298a2dff08e59235da0 SHA1: ef35fea8c383e1d267fce6637fcd3478f0b4b46e SHA256: 316a04c64346dc95ba94cef7f265d52a2867e2924a13f403ffbbb66c642720a7 SHA512: 4296fde591005af614076ab05cd783262dda50ab962e367744634e0855357de4ae8701a14390036f29aca16228ee13a182f46142125657b16ae51c791569201d Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 35555 Depends: libzenohc-musl (=1.0.1) Filename: ./1.0.1/libzenohc-musl-dev_1.0.1_arm64.deb Size: 8503644 MD5sum: 33933c2d8ce5edd75c9746c37cc337f4 SHA1: 4804148db91468abe8fc59b00c0163a21522a9bf SHA256: 43ea51562b8157905afe46eb958fe990b90b3dd65a04f341eb7af6283e7218a5 SHA512: a2b2dfd68e621602c5ec7d9dce6565fcb2ef5c678163156add88e56f9dd6eaff75ad5216d13f309caf3a3b291ad2ca0c8233e46adbb77aaa818368bfbb8c8660 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17578 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohc-musl_1.0.1_amd64.deb Size: 6377428 MD5sum: c37f0f79cc1c674994c752d742497a8c SHA1: c0a665249e937d7f40e2aad632f335f588e0fdd6 SHA256: e55b21cbd847a4fa41f5ad00df7f272242f616297bd1450b0b5ece07ccce879e SHA512: 009cebe80613493c2e3bb7bf1e3ded5761b362ee61f8da84ca75052e0049f8aa41f9f4d9c8b95cf12813138dfc4b663e99ec48b0ec67743a72c937915a41e2a9 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 16268 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohc-musl_1.0.1_arm64.deb Size: 6077162 MD5sum: 4951554ad140297c1a542c0125bb0f19 SHA1: b25138e1ca0ce8695f7bb5407ba17bb2116020be SHA256: 8c11d25be93b7d1304b1ce7545a4e8cac7bc7f4cdf06fd6efbec819c221e14d0 SHA512: dfec943ad94c222d437ba821a66edd2412dc581c23c8dfbd041922e97862744ef103d88b244c4308623d2e9fbf3a44e39621fc168d2bc4373918947a87c5cfff Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18164 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohc_1.0.1_amd64.deb Size: 6400858 MD5sum: e2de74742108b3d82110e5093e453e9f SHA1: b5ba927757b405e462d42c8b332e75f70952e013 SHA256: 7519564d29e690639678a04f75f1a2ed1e337908ca524699f0cb0626771c79fe SHA512: 4a11b12c8024f882103f1973f4cf5a52a05de581981da41e457c2be2fc48d69cea5ddf54f2770c2848d2676c46618aea5fc82fb62bf61855c55728088de7c9ac Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 16617 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohc_1.0.1_arm64.deb Size: 6126608 MD5sum: 23bf911403358e46580c6d4aeb6d9009 SHA1: a4205f2edd4f5bcad99786c8aa5db6c7aefaefd8 SHA256: e35508a4e00ecf7f6e450882df716890ca6604382b0273763fe5a7c68834c632 SHA512: 35a2042a01fd8ee468c98932908c007989dbfd44ca7751e4b1c5e953ddaa840983d5122b097a37e153f82a078445b79e1d66229d9e73fe7b17806b8fa39189c5 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17802 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohc_1.0.1_armel.deb Size: 6720112 MD5sum: bd8f2678e932aad4ef81f02eab647640 SHA1: 7fa61da64faa12f3e0f8130048e16c0a4476b31f SHA256: ff181bf1b57885216e95bc27a34161c49a7bbf588b0edf153141433b8a5791c1 SHA512: 44a57811d2b94d0852d073076cd98a7dbb4874e21b90001ccad677ed7cf4ebce6bbb228f89b3eb0aabb50ce8f1130ff65bb42d6493989c8a2de725c2049b5278 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17781 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohc_1.0.1_armhf.deb Size: 6785012 MD5sum: 5a07ed72d6a60712f387c73f53251ce9 SHA1: 6c98b498b23b65abeed3ec780ea3ff8a2357282c SHA256: 4ca3515a1fd76b7b364ad40eb211439563723f26432a130b1cf7e2ae478694be SHA512: 53a0badadc6e0d8bccb1e3dc59ad25bba161d58befb228b55000943d3d3766957c3bc26f709e1594c327c56ef1bc537148c0e49d8f0dd70de683f0965a4062c9 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 327 Filename: ./1.0.1/libzenohcpp-dev_1.0.1_all.deb Size: 42520 MD5sum: 282db05a35e4942bdeac92e61c0fe8a8 SHA1: 2d14547e3aade8707fbe8a1fed7ab3a4c3d5bc90 SHA256: 1eb361faa6d31e4b81faf70866382af97c843cf988a03f1ae272f5be07cae6a8 SHA512: bf65f7a2031c572968d71a7a58e481aa8bec1206b497f11364cc32c052491367ecda0a2ae1a4ed6c53331a1689ab037a5ad1b2887a262f37067e85826128ef58 Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1092 Depends: libzenohpico-armv6 (=1.0.1) Filename: ./1.0.1/libzenohpico-armv6-dev_1.0.1_arm.deb Size: 217274 MD5sum: 5f9de8ab03bc7f2d09a9466201aaaea7 SHA1: cac5434be73b079913f5b42a71a4dd0d3aabfd9b SHA256: b0b08073524bf54e23d99a44e10e2d342f5956f730ea2d8f14536322ec4a08fb SHA512: 2f33e313e52a494dae84c28ec0d18d853fa317ac11139bf0fab3f46c11d849a5068e330977b7a3270cb49161a0dc37f99be1a9ed9e22ae07334b84d0eb8f1400 Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 327 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohpico-armv6_1.0.1_arm.deb Size: 131244 MD5sum: e983bf009ab4067404dc079ef1f73925 SHA1: c318ff445b411ed2421a64e78467a980d85c0597 SHA256: 5ba73029c193363406ac7d181b4d47ac0ad8e35a823bd957427693f675b93554 SHA512: 854dbe4b62e1e2d21e240797dbb8d55e6bc4504efb4d1d7fa5d9c98790ff7c1547bdf1b111ae38be76272ffac086e10957767bcd5fca6292f49252034d1cbb72 Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1087 Depends: libzenohpico-armv7a (=1.0.1) Filename: ./1.0.1/libzenohpico-armv7a-dev_1.0.1_armhf.deb Size: 216478 MD5sum: 703d16dd74aec2a519e57cc22b14ba32 SHA1: 4217b2a8b7a3c01c1ce33a582c34dc704e320b9c SHA256: 50aba643635159d87a0215486b9df773f04daedb9bebf30f7db74b9b0d786aa6 SHA512: bcebdcb2dac5c0c8acf994c55ebbbcee94d4194b312da409bcb2dd92294100012fc4eaa32d53be4858d0330411e5cf696b602ac582097aa9aa7c934c093abacd Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 323 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohpico-armv7a_1.0.1_armhf.deb Size: 131180 MD5sum: 71fd417119db172cda435e067e1b3fe4 SHA1: 92231c3aaeb91e8c867d7fd5e6fec367f62328dd SHA256: 3b55e32ecc4a15f0a976dc0d1e642cbca63dddb03553da3d97586c953550d775 SHA512: 9d1a9d49d14590a2f504a8e7d89077fe8cc09478bfa829f2d0b0ffe423e9d3aac4e1dbe8693d863af2c97d88d3b012999eeb3b12f0507e909e4ff077981eb0b5 Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1331 Depends: libzenohpico (=1.0.1) Filename: ./1.0.1/libzenohpico-dev_1.0.1_amd64.deb Size: 263618 MD5sum: 0524846660d10e6f9c0743873168c80e SHA1: e6bb9936eae12d2d9c7ca3fa7ecd9e767fd7ea4f SHA256: 3b59b7c0460d2350f4a0b4235e4d9c2fd092aebce18718f1ec398e470efced28 SHA512: d923294d95827c29de612eac382a22f6837cd0b8791d1b762ed314d8d15a952e747f74c3f2696e0d6d34ebc9da204796a97bb756a95ada59841ced7b66e5148d Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1091 Depends: libzenohpico (=1.0.1) Filename: ./1.0.1/libzenohpico-dev_1.0.1_arm.deb Size: 216672 MD5sum: 2cfcc95a843584ab60a87eebcbcaea39 SHA1: ea0742a1a030b3c89ead176fe04b14ac04456911 SHA256: b41546547702d42d15d152a064e729d9a091d52944447de14a95ad26fc5629f2 SHA512: c0522cac1884876a089e906717b0650bab527c995816591ed5afd02491983d55a2245286206041bc7a207dabc65959b4064ba9c1195553ef27843fb1414497db Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1341 Depends: libzenohpico (=1.0.1) Filename: ./1.0.1/libzenohpico-dev_1.0.1_arm64.deb Size: 260336 MD5sum: 816f9ff440898d809b603259fd2d945e SHA1: 2d5a5ab1c374b424e6088c480775629436bc7e79 SHA256: 2c7005dee3a312dc985eca82ddffb417e6a4938a5e84a0e3cdc8ac111e419c0c SHA512: bc3e686222abf8562955ddf7770353a82ce0d618f465d96fded2c5ca5071c4830f5031e17eabc208b3e581a09cae266acfcac41b773f6b4761acd85b2e64ed06 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1088 Depends: libzenohpico (=1.0.1) Filename: ./1.0.1/libzenohpico-dev_1.0.1_armhf.deb Size: 216366 MD5sum: 020702d38bea2f0cb84a0480249db1f9 SHA1: 22ef263d1cfbabed60d76308f3d6802f4abf80ba SHA256: 8509ebb826c6f3d9fb493843282b101a44aae1e73593b0b87ac2bb8ec6b98102 SHA512: 8ffdb4cbad0871980c4f80eea3d8ac7fb0fce732b0d00c7733ef6c324b8526aa246894378f3dd2c618f71d4bbfa2a4e1af5e2e385b2d70808fabfdf663b5283a Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1300 Depends: libzenohpico (=1.0.1) Filename: ./1.0.1/libzenohpico-dev_1.0.1_i386.deb Size: 285338 MD5sum: 5c20ac3aae0656bd92121c4533c769af SHA1: 5a83c1a15f5877f43a4291d1cef30bd2cb04cf7a SHA256: 8e041880a4a83c616dfebd151437d5833898a01762e5188ee7bdfba9d32f8fcd SHA512: be32132c9f5de14e295f63fd3d81373cc02b9f65c26400cfe081e6ab62c08c3e904073db45ad1ae81a882e9bfec140a2540f62a05f442998447f5fc12ca65918 Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1233 Depends: libzenohpico (=1.0.1) Filename: ./1.0.1/libzenohpico-dev_1.0.1_mips.deb Size: 248372 MD5sum: fd9224b5e55e1a8fe2f4f992a78dbbb9 SHA1: 8932f7397ab3aa8183c8c5108db14e0fd5b6d161 SHA256: 508b625dc1672976238ddf43a10a1754d18f91e9db7947d5189d1b98d8471771 SHA512: d7aae13f8c967d7dc4e2d3664f962a36328a094b339071bb62719b47af9e3e9ea75559dad0520be150fdbb583da77e8fb9e25b3980cd6f17f7b73693e4f70b4c Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 446 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohpico_1.0.1_amd64.deb Size: 163464 MD5sum: f3c0f3917aa99845021de0640760e189 SHA1: 9fba5613533330c86e4ba3df8a923a6671948555 SHA256: d59f4e7dcdb6bcb6eec23ff3dc9674b15a67e35fb0523cff550fc983e2de6e9a SHA512: 89701358678b4fbe5db27dd81c92a4e8eec284efb67768eadc14d016953cb4dbdda58329377fe98ae86468cd490866603307b6cab0c1fb0daafe715e25f31240 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 350 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohpico_1.0.1_arm.deb Size: 139566 MD5sum: ce4152c490518f5ccc4a660f808da74d SHA1: 5b1abb53d08b2ba71639855a3ce73019b16a3040 SHA256: da803cb85204be0fae2d4efc522168e83b9e5a0f0ce6123d997b7d2e7d97b15c SHA512: 7ec118aad898f190558592775024b763a03e8618d2e9b2a1b46822ef3787bac2d8e173d1fb191842e89822df95935247e9f3c2f3feb94b6beaff028179128431 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 464 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohpico_1.0.1_arm64.deb Size: 161794 MD5sum: 8b161dc8c504756f1ec70570c6e84042 SHA1: db4f64d69a1a118be2c4b4bb7bc72ec249a43fdd SHA256: dde57212ad8b3f177f5fa1e4262b0e9ca5debc26df78d78e3576c8db221cf663 SHA512: e264a9bfc739d601297984c20f31d99f7096153b2b4aaa729e7d14fbb07f652f02f23889ccd8975dc3aafed3840f3f67e63d63bc1f54d0c7709c9d999e4d7906 Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 325 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohpico_1.0.1_armhf.deb Size: 132618 MD5sum: d4f889be5462c83a4eb794cbe466abb6 SHA1: 5c753ef683b32e9d67618311e2b038b48dc13aaf SHA256: c78b81b1daf15abdf2abc409d2376afdd19197bcddf9f193da6c610da4372c9b SHA512: 299adbf2ff2b7497f2170a156af4b9624b696e8dbd0c64ff2da88a48e65a272f1562e2d6fc5b377ae7f70971b5957b2f033e1b54a1e66e02334c3dab07427ee9 Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 474 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohpico_1.0.1_i386.deb Size: 185738 MD5sum: 60f1308c614ffb982a6000df49116866 SHA1: 062b802293cdf19b7b588c29e3c0c08b0261d420 SHA256: e824a3ed9d647d6f3c0197f95dc99d6087a8c881f4c27cf0f10d4ffd884437a3 SHA512: 28cb31ff38067ac2b2b197b9cabc88d1178684aa17bf1b59ea62c7cc77059167958dd80320b0dcb0633ca16a07e9db9c5a9006646ceb76dc3d991c8491a5f042 Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.0.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 430 Depends: libc6 (>=2.12) Filename: ./1.0.1/libzenohpico_1.0.1_mips.deb Size: 146124 MD5sum: 91d9f925bff643735b9fbf0c6c5290a5 SHA1: 729bcf6862a8c586fec1da020b0cbfea02ad45b0 SHA256: 2d16cb9903f888ae72126ebc60f4d4d6764500dff3e21693f2bb515454cc3ca4 SHA512: 4cb03cbbb49aafac30f837e71cc90b3f31afd1d14cb5cec5b97ff6c341bb426281a19b12e30535e70939ed0e36ec4e0ea484496dd0d92e8b839eba58a998de38 Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20839 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-filesystem_1.0.1_amd64.deb Size: 4600132 MD5sum: 7c32340949dcfc01af31374bc2ace34d SHA1: 48ea8d54dfb2b6642b8aaec67348ce6a77ab4b6f SHA256: 63858199308acadafc39b2181125703b175a2da106153c8dafe0328beaa6a78c SHA512: 196331661a044fee481caf2d24ebb19bfe50701a91857a91c60314852c84a07dd9549fa75b1786ba54631ec2fd8cb436ae972d1092c5279a32b2beac9844250e 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18951 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-filesystem_1.0.1_arm64.deb Size: 4141072 MD5sum: 2ceb58b9d6af39a7bc8fe01fffd4f6bf SHA1: d78da0347dc76af5e4bab3643cecfca4fb4a49ac SHA256: 48b8c63e19e4eaffe75e997d105e91dc1974dfc2d38bc3523f3a8744ef7742fd SHA512: 4662f68564c83786de527400578d828baab9f6fb5575892e7686107607fa2d85a2b97939733d2328c0083a65a442839400131a189fe313fa9d1a2601e74206f2 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16510 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-filesystem_1.0.1_armel.deb Size: 3909360 MD5sum: 1508277b541328e7ce4e5ee1aac4aaa2 SHA1: f452047ff4700d946f2c92f62036d2c8e3fadf8d SHA256: 214edb9f00a0eda58c418a8e49da0d5f856feda8970f9cc0e282e586e5c253ab SHA512: 1470d1770261579791dafb546c985f190edd61a1946883ce8b8aab11629780366f8d26e9a826e3a4573879e76773fa85a31e08985c97bd424450d97e38cdd29d 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14625 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-filesystem_1.0.1_armhf.deb Size: 4009208 MD5sum: bab17e19d2538c95476a4047c3e33cbb SHA1: 5403af9801c372e3ba7756e7436c7b183c40bfd6 SHA256: 9d1452e97932fffec5d7352f09c6a7c7886f0ef271773bf3eb84957e571d98ae SHA512: a21e2e84d801ef05466eb5930402e3edc64df14097434d639665c407d378c7503c069ed9f7ebbccd3a08757b7d5be4328639006ca01422329bb2f9dc27c5bb35 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15711 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-influxdb-v1_1.0.1_amd64.deb Size: 3129412 MD5sum: 98172b0ba2baa22717e196fd24a0b1b5 SHA1: f512280f94b75a5b9c2e387450d53186904928d5 SHA256: eae07323bcbbfcdd04591c25c8757947f25bd69d6c28f00e81b1029e932c1828 SHA512: 4a0af8ad21f680b080e49554d77a7f64d825848bc2f7190bef956ecf1ff954b583b75b719f23f43dcb2f50ddc0c5dffb19141ac9d9a23a005e9c667f3b17c672 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14036 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-influxdb-v1_1.0.1_arm64.deb Size: 2811692 MD5sum: d53b11c90d569919e14ed05d07e6ff5e SHA1: 5a3a545d442d1befc7362afd9125cd9bf219976a SHA256: b0704f16faa50dc6f75e9a5dfcf3d98fa96c4abc87851c838c155a78e6eee448 SHA512: 382f0bb5a353577b66a8b32c586efe86ecc2fc2f7753fc7b7f0f8e3df24363e0efcfb7f3375d4b6899db5bc7f38832e2aae45a8a8e5c6036ec6675cea64de469 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11805 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-influxdb-v1_1.0.1_armel.deb Size: 2552480 MD5sum: 4d4bac08045eec45f00f5081009cc5be SHA1: 8bc9841bebaea926233386ae8c37a1062d035097 SHA256: 645ebaf2365cc31ac98cc7518d4ba86d783d8146880f9c3ceb143c8de37d8ddc SHA512: 65f85360f7597a8adf376975025be6b8dad87fa1da2270922461f74c1dfb4107773867649fca1d1b4735915cb4addf4de51f065e7ee54dd1d8038a4f8539fa87 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11678 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-influxdb-v1_1.0.1_armhf.deb Size: 2541652 MD5sum: d3a5809051f19ef6f07a2dcf260e468c SHA1: 6c0e387958a4516d56069e8f72cb544991e0a1a8 SHA256: 4103f23a4429f184bad3c8084a1b490e85291bcdcae0459342a21b8668d2aaeb SHA512: b283199f37db14d099bfeedfcf1e18555761f7dd08be612e36daac557232cf53239a86996441e2afc2ae0df6ed8edcce34d6a7f96fa00079622fb4db9e00a395 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17302 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-influxdb-v2_1.0.1_amd64.deb Size: 3804600 MD5sum: 8ab09b13b11e4f6f52bedffe81148fc2 SHA1: a5331f7d65ac3b53c7646040aea076813eac54cc SHA256: 8f41543b59c2d22780f9d0bc85d2c9241a6f383f81ef823a42ca01054f5cdf39 SHA512: 1ec6b46e5207005f76c393068b239d898858164bcc9ded7b1fbb039cffeb62a8a0ba5541cd0fbb5992a97b4d82e9f4a366ee0be22ea5e30dd5fd65cd7a14a922 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16262 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-influxdb-v2_1.0.1_arm64.deb Size: 3484528 MD5sum: 1d542532e9a2f16e7b74c545c6f18c6e SHA1: a7139b1e0bc6fa9e4c32d5897561014a0730e199 SHA256: 1c295b8d9ff1466a877b6299b0b8cd5abab25a9a52fcaa77ef5db42b4209187d SHA512: aeedf15285a65e46bb994d3feb81aaac9724e751bf187ab2412ff5e4f4c1488fbefbe48a6ac7c70ae1e1311de7d14c63a22b6d5d7c25d461437e46edab665f3d 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15591 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-influxdb-v2_1.0.1_armel.deb Size: 3468184 MD5sum: c236f2f79a3373d3c9fb3933c34b28b2 SHA1: b599cbf96345b36fd06dcfaf73d77bf0725a8258 SHA256: 09def41d803b8226499fdef41ded7f56b2422dda6be230765ab1e19f341b808a SHA512: 7d8343547c6510e6d198f8f37e3fe1ecedc543860e5105ccd33ff89e58430f515960eb799c0c3d864128b91495de1f26bd74584c85f6ee264b4c0096b2ec0855 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15489 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-influxdb-v2_1.0.1_armhf.deb Size: 3513608 MD5sum: 7f8c08cb696dfa661a893bb79b37d67e SHA1: e8645c24cabef11053c772fcb6c0f4d11bb9a67e SHA256: 53a0afef49cd64b1407a310b3e56d4cb0142d452c48ce2f61e489195aa79b569 SHA512: bed942216e17863ef08806364901ba47e35ee2096c58f17bd6d34214d378b8b97989952d3d35c0c3e6ded11174ce31b65de9fff0cf5026dbccb5b01c7dee36c8 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19383 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-rocksdb_1.0.1_amd64.deb Size: 4328812 MD5sum: 5e6700929233042b809f6c7ecf08c82d SHA1: 3b1532294eedf4b739d42ea94ce8d1decb6087e7 SHA256: fec40846859615f9c4650cfacfc82c00780bc31fb6f1d1b1ba92c48b21fdecb3 SHA512: 9871d4b562545f1c1ab534b1c0390e122187013b9c17103bbdb350916f274f131a6ca7bc26df9d876789d3495583aa053874adad972ea4ea47ca21e20f5309da 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17505 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-rocksdb_1.0.1_arm64.deb Size: 3890188 MD5sum: 00cad25dbd1edaa76fe3fe0f6f5dc904 SHA1: 91b4b89470dd1cad6c054e0c488901be2588cd74 SHA256: 603063b7705d3d179de15d68228f5872f0e516d321237fd7797647395994b143 SHA512: 79cd1f06a7712a841cc715c082e29267e83d0ab29824012b86534d480dec432ac1590fe155d2b2e4b9f90a2e55dd264b43ce13c7f7e976ec0845b48642da5c81 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15304 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-rocksdb_1.0.1_armel.deb Size: 3694728 MD5sum: 106af66b6ab6d36529963269bf7f85de SHA1: 2ba73dc2941830c9e81d7f0323cda87caba6c171 SHA256: 287976d33fb11bd411ef77efa88439c478c0a4946f640e8cecb5ab2bc1cedcdd SHA512: fc49c8c1329fa157eea02235ac107522bafb430ac1c06a1df07e6c5e23dab40749623e0ef06ea545f27545d0f7130635931d3a6a4edfbbbb0aa5a987a145d927 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13400 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-rocksdb_1.0.1_armhf.deb Size: 3795596 MD5sum: cb2595aaaaf9fbdc4fc16bab2e690b41 SHA1: a1eaed3c38c2d53cb6ae3862fa2fb793d41858ef SHA256: 22895e21cac6922cd2921eacae2d413782081ea0c9db563daf143776210a644a SHA512: 1af293904b60cabe9fe7ac8a4e0b622f3c1b5916847e58a91815784feac3c5a57840e6b227b739bbec0c7823fc88a63cabb84c3b09dbcf9ce07b5f8f0b50f00e 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27244 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-s3_1.0.1_amd64.deb Size: 5510424 MD5sum: 678eba5ffe555131e2bb65494bc88749 SHA1: b28024dd948ef805ec606ede28c48e731d7882dc SHA256: 4265b22df76aaee9a913cfa0f66dfac3d04e1f73b171fe5b8cd0625b98070d05 SHA512: 372f5914df05e6e65ef1d0b645dd109a3b9003fdeeda2d3461c0feea0a8d7455a22d659019a84837aa5f7af506670e28f14a84bc6f36832c06e412bca0b13aa3 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26495 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-s3_1.0.1_arm64.deb Size: 5224788 MD5sum: 9f6ae09312c3cead6f7ea0a1dff919b7 SHA1: 074609eceeabcd132a478bedc75ef9ee9c4b9a5a SHA256: c645a01f940c9fb79e554735dbee43ea29f5090c1fab980f7e1cc36e01359899 SHA512: 130484c412c1f62060c4e65b91380959681dff1be9d00e5e475b8894125ca616027306655156acac4ca89911d9ffa10eb2a796dcc24381276182e5a085045a37 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25158 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-s3_1.0.1_armel.deb Size: 5094240 MD5sum: 1f74b85bca9dec8c34a127d59eb98d87 SHA1: 9381929acdcd3b9c364fa10872bc10941162862d SHA256: fd8e9ecb2215c291ca8f281555af8ba366b856d64f3f68cb497780338139b8ae SHA512: 852e5c97181ded2610e6f1c486cc6d1bd516b0595f91ebc8109253e6331c57965c30fb4d633a739d0aceff0fb3deeee83d7b73ffbfbbd6ddd29ad1ff1bbb7d1a 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24954 Depends: zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh-backend-s3_1.0.1_armhf.deb Size: 5140328 MD5sum: e4fae08c4703a997d213aad816361814 SHA1: 884096089aca4a6c6b3d3a583b739512da6ba4e5 SHA256: c409dc222c241c4fc9d7ecf855f049f98f4acccda78817af167d38bf1711f0f4 SHA512: c43504c9b2386d7a41063a883bb49636493580bf66650b80708cbbda9885b2fccdcb168f8d582d11cce829b99581531b374e21d96fa9533d9420831b64e0ef6a 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20681 Depends: libc6 (>= 2.29) Filename: ./1.0.1/zenoh-bridge-dds_1.0.1_amd64.deb Size: 5287552 MD5sum: d370fb396ea123b0eb2e00b771dcaaf8 SHA1: 224e2e1467b0b013bcf0834f97dac9f004a55a5b SHA256: 3676de2ba73c9b396f4fe3d812e9b7df7fe67692b782e313d1187dfb743112f7 SHA512: 947bd0d3ec00403d8a1e7f245e0e6cbe600173357bcff8d7f88105718a89b6c7df14eaab8eb2967f3eebd044b3d25b3f904bb7456e9ac83c651775cde4cf19a4 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18866 Depends: Filename: ./1.0.1/zenoh-bridge-dds_1.0.1_arm64.deb Size: 4779712 MD5sum: 7c41b64f6c419224aa3b6df57a8e15da SHA1: e3b392430a8300d81bd66be58f95177b624ac8ff SHA256: 9c5b46fb200988351bc44317bb25d349ae493fbd2b72e2fb89a010aecd0f965e SHA512: c65a7cf0f0803c2b9d494db97e5f0587a835ff3d1fdd9e1e7a4551836f2a41fe1dae5e1e16bf9743406f71e6518a68c39c05d1284f5967c8aaa369d681d39c1e 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20040 Depends: Filename: ./1.0.1/zenoh-bridge-dds_1.0.1_armel.deb Size: 5052296 MD5sum: 8380a1178b376467b8419ef943671fcf SHA1: 7f0fc14d8a3ac53317c8dee4879d2e0bca6284ea SHA256: ffc5c3a5ba16de2649c7e55d49d52c466415af8bb2665d39c7296243de214b26 SHA512: 142c4f87075bac8cf0afaf3bf4d91dd3da074d5506e4d88c56a30d28c86301ce394f8e9f72be85f496dce0e85e20c89761b75e916f88951671208fba1c00601c 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19526 Depends: Filename: ./1.0.1/zenoh-bridge-dds_1.0.1_armhf.deb Size: 5102276 MD5sum: 0c8ae98a0254d76b42d0bddbb792e58b SHA1: 287512237b6a5f72bed9208df7109f8c034c6393 SHA256: e68d70981e67c8a3d68327b84c090643bc87618721308ad6c066d82d2c16cd95 SHA512: eae8f613f4a98710a38542313b36568701c9bf71ffc4e58d4cd703dc7f8f9d5f18bf853c851ea3d516be0c0d44520d88df0565b4d66d350bf32fca9cecf29f62 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20530 Depends: libc6 (>= 2.29) Filename: ./1.0.1/zenoh-bridge-mqtt_1.0.1_amd64.deb Size: 4954480 MD5sum: e0d71e281657e73759e6532aaee60ccb SHA1: 8d58e0b3f34f27f9cdc17bae6b5d1176366fb329 SHA256: 53be20fcc71f12c67e119cd9061fa5cf977dc4fcaea64fe535a8299b45d0f0f7 SHA512: cfccf762f2e79c2c58efafd3f82eee53ffcf8ee0efd1d5ed5c25cd152b14184cfacda0083a5f24a7dcd58b5025e592354ee6cbad11362972c9120a206e6acbc0 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18755 Depends: Filename: ./1.0.1/zenoh-bridge-mqtt_1.0.1_arm64.deb Size: 4477836 MD5sum: 7a707d4ce02ee6dd4ad9c679723ab3aa SHA1: 7389fd0eea3441d88fdc82e2f455997608f19c87 SHA256: e72e1bd7ecef1994bfb99047f5a648b9ed016d48ddc8be577dacc2279fbcf2fe SHA512: bbeb056e1a57e4e4f1088c92b9e834386e2c288f9058a52289019ec8a25a75abe92ef69a2fdd447c015c6cfe6d0597b7be7daf3bedac30b09af8579c096a5402 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20057 Depends: Filename: ./1.0.1/zenoh-bridge-mqtt_1.0.1_armel.deb Size: 4775396 MD5sum: 9eb7d3dbb0905a2916f51a52b46dea73 SHA1: 7a784101aad20ff96cb5e58026fbaf01a24106e8 SHA256: 076d4ca857ceb6b5d11acc7a49643cfb2cdd6914698740eacf056b5ac7141295 SHA512: be24748d9065d8f003798f605fa63017fa31c61315ee08e48d99149f1a35d4506efb07277bae69ca5ed5ac6db216bf4bf8b28f4a5745a83bb1f3134e6348fc57 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19783 Depends: Filename: ./1.0.1/zenoh-bridge-mqtt_1.0.1_armhf.deb Size: 4801176 MD5sum: 53b5999b72c8a92f6466a5628273eeca SHA1: 890283ea0d78400d70f92fa648565efabfd04f87 SHA256: 14d179a0a9ebb3b05ddaf66401cc0fcc94a1ab92d7f53dfd8e8612aa120ce071 SHA512: 69634eccaa4307a0a2905e6ef4e0285c447bc50384c32c919810a764812f339a4ff96991fbaa0c0ba59b1180b1e8f1223d3950f4f3efcf551078e0a9a1c8a96f 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-ros2dds Architecture: amd64 Version: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21238 Depends: libc6 (>= 2.29) Filename: ./1.0.1/zenoh-bridge-ros2dds_1.0.1_amd64.deb Size: 5391124 MD5sum: bd1779c2177ae3656600ab5e29ab56d3 SHA1: 1cf5f03ff7b1c1c6c6db17d39549f66ac13affeb SHA256: 972319bcc93304f6d8b25c17df20da6907a18f7a3cf6224aa43f98441585891d SHA512: a9dbac5845fe9e40c572bbcb7e079daafcca8b8bf773877241dc224abcb6c3b85896b8d9cc25fe73b13349d6af719138b7f3e13ca06733427e24fba0a8337da7 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19395 Depends: Filename: ./1.0.1/zenoh-bridge-ros2dds_1.0.1_arm64.deb Size: 4882144 MD5sum: a339cb38648352105b0226c53bd18a34 SHA1: bc5e69ce69cf371a31a37540826ecd6aafa5f230 SHA256: cc911d1d03e4269275a06df204bc859260d545f8fde5788610218ca36316fa24 SHA512: 8ae18f6b325695629a3153e345d2ea4b50d4a7bd5fc437f2233170592871a2e4876923b6f46f5f77939e466d969ee840c69adfa1db32e3eb616f16a6803a7cc3 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20574 Depends: Filename: ./1.0.1/zenoh-bridge-ros2dds_1.0.1_armel.deb Size: 5158480 MD5sum: 06993801c5ce2c57c8a1d29327a311ba SHA1: ae90e379fe8b680db3f56146601fbc2d731fbc4f SHA256: 0ce0e2bc2f9df864ca1f9a881bff5ba603b2c41218556f09954d5fe32c6b9119 SHA512: 18c932a7aa116f478b4a75963791669e89d7aeb73310004b4451b7d2a39305471631191033780e7e17dfc9d02a3e437f811c9873d8b0d6fcae5f7d80b52564e2 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20065 Depends: Filename: ./1.0.1/zenoh-bridge-ros2dds_1.0.1_armhf.deb Size: 5213452 MD5sum: 37a908560b6334bdb9bf59a65743877a SHA1: f9b04af92205ec6ec21a38bedd4350b684e4740c SHA256: 5a88fe137ace110d28a16d8b8b73234977e9c634a3e852b8c352b819c5708bf2 SHA512: fd4e2825674a70b38790a333e59f85850c1156b3582eca37f34b496480d533e3e5e438f4f3752342f2f2224f90be9339f54a2d7aa0386d5295a46ca508f13afb 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12828 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-dds_1.0.1_amd64.deb Size: 2576944 MD5sum: 3f042014286b23f447fb5bac600d34e3 SHA1: ff5f0168fb7360fe299db2905e27f47ff158246b SHA256: dfe5ac6e038b6c57219369fa2e5141288f74af01a695b56e2a4c955df8a3eb48 SHA512: 7210ac6f1306422fcb3e5b371ca508e578034a706b769e0ebb0f8870d290d4178089ec2be655a88f15f165a7b0252e1aeb7d5d5f7bfa67df795847c86596fa34 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11591 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-dds_1.0.1_arm64.deb Size: 2338824 MD5sum: b2e26f70fd2123d0863f44444bd2c58d SHA1: 3798e3c44e7a308eadc23829085c7b33b87ededf SHA256: 6485d5f91899c7261f7c6ede5c5bd6af79a4897577d59612e1d9810fdd927f56 SHA512: 9c0e26f761232b213c29878b6b1e8847b5179a2ebfc0bb7a93ed411822ba15c2e31f8fe77da503b4f1cd859c0917e500d316426dc17daa1189d2ea9705b5ae31 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9649 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-dds_1.0.1_armel.deb Size: 2188312 MD5sum: 7e6ff6200e7d07e5d4369f3992fb023f SHA1: e990114618dc4ce69f18dfc43a085a2b760c0d12 SHA256: 1bddfc330d25ef97a410fb800ebcba82a99550113decf95be25218080da98628 SHA512: 53a47757fac66ca2ee46dc598f5fb2f0260cea5b9e371487a87b5f810d05ac1ebb04b1a3d829443d17278cd0ee97f10cf6a1500155bdba2112939989b2d48f79 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9271 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-dds_1.0.1_armhf.deb Size: 2196628 MD5sum: 38e49b4ba70b4b7c2f66fea0134c8d79 SHA1: 04511500eeb0862ec720427b00079378665b7caf SHA256: 8afaa8a5683f1e2256c5dea19af74f072eed36ab90db4ec3785afa46ba71cc7d SHA512: 8fecbe7744c42c94371d8b542ccf694963603e7101a772984573f724b96aefdd53fcb3a45f7875e3725df95fd4003934ea2e5c97880e9edb85ca797da9d1a77e 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14031 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-mqtt_1.0.1_amd64.deb Size: 2872436 MD5sum: 8df5af69ef5c30ff9dc1c8d1e368c98c SHA1: f5dc124e0b8070167fbbadf85ed86353137324e3 SHA256: 54969e6fb3c7c17a4cb45e0ffc11b93eaf292382e898bbe6fc80da84b0ebf479 SHA512: fb867b9eb8cafd1f40b8a64cdac5263cf6d7396afbb92d87cbf59bfa7005bc13fb5d1e4ee506a18df6b6c9633c863e1bdbdf1232937c938ff1804cd6d7509643 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12756 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-mqtt_1.0.1_arm64.deb Size: 2565632 MD5sum: e2204d5e89e27cceecac072ae4f12e09 SHA1: 0e78bdc72e7794a1198b957acd989c7391ce228d SHA256: 605405dbe7ab905629b8b978b91ee738de2891769c0c6a2af794374a5517dd31 SHA512: d7cc0a2f0b060e3bc183ebe9fb5df4986fefb18c1441585c26ddee73989d5d9914bad5e7d08026299273c8c805ec006c51b7c2e29a3ed84e21ec0ed94d774b43 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12756 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-mqtt_1.0.1_armel.deb Size: 2641756 MD5sum: 478adf6f2d70eac3c5b9eb316ed7e82c SHA1: 54532dfa53307ef9c822d33f99d09284587d93ca SHA256: 9b9bddae637eb7dd2aa2b0657f7d55977490969a2809b912799ca3f4a9c03938 SHA512: 22485a682bcc090d2b70e6471dbfed82c3031153a2367f4111f6d33a756990e173561ea3416d07f2062ebd6eb84f919b0d94cf0c041d8f8e2dd7fc3fa2284659 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12672 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-mqtt_1.0.1_armhf.deb Size: 2678616 MD5sum: 2493dc1d191507254f9aea8cfdab73ee SHA1: 4e46cb203d161ff4fd2b5f9de4b151cc1bb6ece7 SHA256: 8d579f9384cc67ead6d26422f8e08136d1bf2293a1688c7d5b04e8bccfdf4d4b SHA512: fef8477bb8f003df73b503f770cd208794609270be2a0b662dd3f4f5983af4c094acb612dc2efb4bfd64515034811566e0aff785648897799f7863160565d09e 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-rest Architecture: amd64 Version: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10854 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-rest_1.0.1_amd64.deb Size: 2086580 MD5sum: 1e30b27076ef09f0132622f95bd684ef SHA1: 64f5d8204db86ce8b4f4d8c1d3b5802472970ce8 SHA256: 914feb4e452e26c2c2280e793db63a19291139dc1a6c5d5addf5102721ddcc9e SHA512: 6fbc372da4076f4725bd183c25ac082a34cdcaa8a9c3c3186fdc7a186b0611f42aa13df556605b8c5f8dbdc4ff02124f8c7a108f1d44b679a29b5710454d5604 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9839 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-rest_1.0.1_arm64.deb Size: 1911672 MD5sum: 0190097cca80236bee172e1aad6ebbed SHA1: 8cc63ead41217507beabdde701e11bfdeda3caa2 SHA256: 5518a3abdca3bbac8ec79bba9590abbe21bc8243ddadb100be9a13341822a3cb SHA512: 61a9ee3d88c55804ac901de5f7a10dc8d1e1ce2b48671115b7259d65ace2ea23960d79cb012a7ee227a8e609978da7c6a510a75ef76745483a9eb3baffef50bf 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7981 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-rest_1.0.1_armel.deb Size: 1781660 MD5sum: e1d9a2a03e641467d0014a9064f897ef SHA1: a8db0450f52049d712b036192a8ceb78a8f3a3d3 SHA256: 49d21ea0968eb6c03b0e0790bb49d0f9d0bf3a73eca7374fed1279a8c834e574 SHA512: 0372073ae8d7b2388bed65204b7ad4d9d63b1dfa7fd0f8f7adea5202b8efa29f1db6724c19291c159467cad6b34e5c1648b36c31e4e0aa088b6c3ef88e9b0766 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7887 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-rest_1.0.1_armhf.deb Size: 1771244 MD5sum: deec1c84f1cd7c31411e8f7792594dc0 SHA1: f18fe47dfc2f36a5f2541818511429832fe1ec6f SHA256: c7654c4d4575eee536497dc25c62bda3a162cbae4c72854286cd6677f3b84236 SHA512: 8a46293c8afde4cc238e0cba9f91404c087aef8316c390e5cf9d156b140c719d913e2ce6d44aac9aba70c3a255d4d44d7a1d10d45afa8f367c54de71760f0d51 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-ros2dds Architecture: amd64 Version: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13371 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-ros2dds_1.0.1_amd64.deb Size: 2672340 MD5sum: 98ddf4064af64b303beee71210ec2a79 SHA1: c8a7e84a7c22f8a38ff631de09155bb83183d74c SHA256: 96faea219578ea23acbbf573cd69deb082c2d466d648192bc4903e065c3f2a77 SHA512: 77ca4d713375321805542f94fa769cce038f563cbaf49ea73d135324ad46970176d74ee906363dbeb613d3a5818795f39ff19b91912f72b777b51173208d379e 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12095 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-ros2dds_1.0.1_arm64.deb Size: 2433448 MD5sum: 40a9be33b4cfcec11f81cc092910fa80 SHA1: 99a1f67c615f54939ee77225fd43204af1bbcaf2 SHA256: a187291c772b2e01695efb4b48fbebfb3f301abd2348eb16118bdafc515961ab SHA512: e492cd13cffef57a75c3c159338771c202dd3cbefe79cf9a88bb81fd7727c5b921e703e14bf3abdfd8f5460166fc86076a4dc25af07039d29efdc584add9ac7a 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10164 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-ros2dds_1.0.1_armel.deb Size: 2289336 MD5sum: 8b65bf6a8c1de61985766e800da25e6f SHA1: 0dd5294a46d41db8783f9b1f335cc6ad9fce4deb SHA256: bc87397587be59cd8073e29adbace78ef63352fb624826a44add39cec4efa952 SHA512: df156276990c0f250b98f2060ec117a3c776aa916b9f348be32e0fe0075310100e4332be039a3c7fa56717336e850e4707c6f9c1426dd762a29a2b308f7290c2 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9787 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-ros2dds_1.0.1_armhf.deb Size: 2300108 MD5sum: 4f53bfa941bb702626dc21771b78db3a SHA1: ca79e2c1c6bc1d443f2b0b66df8068e8fea80b4c SHA256: 375b8f15f21a6ad285fb2b7f7cb84f5856a15664a28a6bcd00088c60e3d9d821 SHA512: cbb14f290f6b62934bc2a01aa502b621a305c6a4e87e094891b9d65f9144f7b66c96d00923d7e0626bdef0a4f335ca836377ff71d8f4370cd93a3b04eb4a2afe 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10583 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-storage-manager_1.0.1_amd64.deb Size: 1976180 MD5sum: cfe00706a7e96696abece47cc4e0f4ff SHA1: 430b11f59822845210c77362deb9bd3e29ce6dee SHA256: dc1b8d8973579a95dd7cd5160893d0df02d8dbe516afd4c91ad828a69fbde131 SHA512: 857e4474e249ba166b073672e0fc9295858224c56e387b6d69e0f9e850d954fb1b4e1f2f7f30130e5f50d6793187ed096863042e42160e5be545a54eba84fbf1 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9559 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-storage-manager_1.0.1_arm64.deb Size: 1805192 MD5sum: d66ef7cdfdb4d91defb09f017f7c9e04 SHA1: 41471f0aac37af91e54f3ea6c6d4c77c414165e9 SHA256: 1f051245827bc202a16dc892e2d93d510e66822991132edee137885efe998fdd SHA512: 93b0e3134c3023de414d6dcbcbd26c4539842e062b815d1b95480522bd6482ad94c5ac2eeb63f875913b67d6333e59c2f991f7b605635490b881cca7b8146ae8 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7734 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-storage-manager_1.0.1_armel.deb Size: 1698140 MD5sum: ec3ad7ed5534ff8d2cb4d43d9fc59f50 SHA1: e49dcb3e419069408287dfef9e5cf040c745ffcf SHA256: 8c5ee4ac0fc20473c3afaf868c56bbb3d0939013acca81f4cc112e7541f5bd6b SHA512: e0634eef398582ab820fb0f8042a51e1cef9a414ddb3b0467058b2a76a418605b7c499f275c3984ebe7b5f3e54853d67e9107ff76ad865a147c6a5c56f8585fe 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7620 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-storage-manager_1.0.1_armhf.deb Size: 1682852 MD5sum: 57be9b2e1a975db2459a3397b457c46f SHA1: aae720a92e77787ceb0e6276d68da0b19fa02dfc SHA256: 67852e3758007ab7bc4249d46afe5fc51d391d08a523db950404120d74d47c58 SHA512: 5d3e9c7dd6ffbb25b40c656bb39bc2b47dbaab082f7077e032709e90f3bc379e2a99be87ec74ac0ea3da970983febae61535c68c8cce070dcb34bfc29258ce5a 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13290 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-webserver_1.0.1_amd64.deb Size: 2517568 MD5sum: d461d7b993bc065e8621e1bb5f55175a SHA1: 66ee3617c116e9ab0aab2a7369b98ce53bdcba65 SHA256: 8445c96cf2ec7228d138c072515c4c0bd6678c97e9b8667b5f67d9328e850857 SHA512: f70c9faca9ab6ff0551259e4d0fda919399c09403de6964f02c4bea9ff671b1e73b27690715bea45fb85557ba0dabcd5e9eb33878363b15e4b027eef05a383cc 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12439 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-webserver_1.0.1_arm64.deb Size: 2342584 MD5sum: befae94d5fa576f4bf491ef31fbb8991 SHA1: fdfea686e65ac2f4e66a148175e5dd35ba4696a8 SHA256: b46fef5b11f07f5142c98ab7657ff8375c2368b70b08a598cdd973e5b354ef8b SHA512: c320dc57ff75bd3e5fa340bc91d7a0991f82e1c88482c4a04e86af12c43e55e1deff30e5bd690853fc273d3eaf84aced8c95c31da0473a8b9b8e52d879f1e580 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10211 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-webserver_1.0.1_armel.deb Size: 2144692 MD5sum: faa8744460e404e687d162e79e04d375 SHA1: 9fa27e451343c9e6f6f3a07c9d6de30245bc0980 SHA256: 55a46e4d7dd329ea7c71d7a1880a002f936ce064053cc308ac9342af7017f983 SHA512: 0c4e03973aa27730a68c6157b6869eaf53b7feba171402c7639e60d27b5ce6118244a4a425b720ab9def115f64593cdeee96b09e062e2cc8042cfa5803447595 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10081 Depends: zenohd (=1.0.1) Filename: ./1.0.1/zenoh-plugin-webserver_1.0.1_armhf.deb Size: 2131056 MD5sum: 420d4a9b67aced20d05c320084de56d9 SHA1: 09726ebc3e6c000fc4664481af266b7c3577729d SHA256: 8a73360574cbaccad1784f898f6f8b1f9d844a546c819f25af25c042f08c66c1 SHA512: 7e410b2fe1ec3518f811fdee36a7425bff2f721ebf41d8bac8f68d1e6c63cebaaa4a0407186bfd6326394fe8051bfe9b36f437daaf0672cfe1ca2a5ea0efbc31 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.1), zenohd (=1.0.1), zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh_1.0.1_amd64.deb Size: 17568 MD5sum: 4ace6c85c7f5228b431fd54e832bb894 SHA1: 9eeeb358662a220eb2bbf7fa6649b2c2cfd574e6 SHA256: 89e23b55b74fd92c938754362c02533d22039376ef0738577ac25857494726e4 SHA512: 17a32a8ccdafc9472dbf2977c134fe0c94b4ce471badbade8d32cfa3dc34f5f83595d9ae81cfec007d30f9982088ec941c2c28518f0713d5855772a52b8a9a74 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.1), zenoh-plugin-storage-manager (=1.0.1), zenoh-plugin-rest (=1.0.1) Filename: ./1.0.1/zenoh_1.0.1_arm64.deb Size: 17568 MD5sum: 48686a613018381006565efa9c9bc9a4 SHA1: bfde47be8041bf0d3890ee06af8ed87c194e2899 SHA256: 06eee9f3b3681eebc145577b9109d4367c7c8231fc11d9ec767e1efa85d1f159 SHA512: d237eb6f697abfae8153a3ca93f95c22bd73f4dce7f75f5855f5c28e36953c223a2ee4822015400da9e301708bf8dd5cf42b375e6b2ec43e85c19b82c4bc6221 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.1), zenoh-plugin-rest (=1.0.1), zenoh-plugin-storage-manager (=1.0.1) Filename: ./1.0.1/zenoh_1.0.1_armel.deb Size: 17568 MD5sum: 3ebe1666b55d9aed952ab9eb9befbcaf SHA1: ed7eb492cfbca57dd03dda839f988a1bfe8995ed SHA256: 81b0815fbfbcd67a3786cd7319340c68a596bf6fe0830566276864be9f56d93d SHA512: c6c338456aaa2ebbd38b9ef3d1c6be85e5282c5da89bcf2a459ff94e459fc54469a2cbebe3dd45e6a11046b68f610cf89353a87a06a7b391f2550b903d179e38 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.1), zenoh-plugin-storage-manager (=1.0.1), zenoh-plugin-rest (=1.0.1) Filename: ./1.0.1/zenoh_1.0.1_armhf.deb Size: 17568 MD5sum: 07f3310e5075130214104b8e0fffdc61 SHA1: 0776221c1f549be7dbc11e7df77d9fe1a477d21e SHA256: 7eb5cbe85a521a621a310cd8b56a81c61f02e5f3ee654db7fc5e350b52937b5b SHA512: 051a2a42a38f46c4e4e4a6efbb4872dd2c4cf119735d3851c44144de86491669214e5da3eb9ad1df8b0d044a91b27a025c872bd6323b3d694a3fc93568849c49 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18069 Depends: libc6 (>= 2.29) Filename: ./1.0.1/zenohd_1.0.1_amd64.deb Size: 4429692 MD5sum: 4dc0e03ae385f3e4a9f6b596f5f0ec11 SHA1: 41476ae151063924a0424323f9de4b962d71ad13 SHA256: aca3209956da69fb88acf63aa33cc68a162e1c63e327d100312dc09aa2acb9da SHA512: b0de129cd4f8c98b2b63643412e12389a5f49667100735dfc0a21e33d31e1e5e4b5c281714572675e5bd3a31c420867820d01bdb30f16e04512be58a3f1c5bd0 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16215 Depends: Filename: ./1.0.1/zenohd_1.0.1_arm64.deb Size: 3988704 MD5sum: 7fb86ebbcab3ee27e9531d5180b516d7 SHA1: 717ce8efcafb187a281d078e6f7474abb20cd446 SHA256: bd590a8f9bf58913a4f2a8251273c0886798b33b55452a0047f247d520ee6eaa SHA512: d90e789ebab8ef111da8563546fc25dd99905e2fcfeb62a12ae08f1f7dc49b77ad26eac2155c678feb0dd0328196eed25dff086852379b43f3e0bbdaf9b07f76 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17572 Depends: Filename: ./1.0.1/zenohd_1.0.1_armel.deb Size: 4334448 MD5sum: c0f1b1d1282d4982be6fd14589a44779 SHA1: 05941479fd66e92db2e4b83651be678a107abe74 SHA256: 43aa71aa8a8451bd3194b694ac5339a2cea96882e1bee8953b4ec25edac1154c SHA512: 67cf25e12325f35e329ef864ad103cfc9980b51706dfbc1676e98f95d1d8691c616895bfe86c6b18d324db6c9362270fc0183b951e7ec1beb5b087e901b87aac Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17355 Depends: Filename: ./1.0.1/zenohd_1.0.1_armhf.deb Size: 4395004 MD5sum: 451b0d455ebeb863f7bd008b59b2ec2b SHA1: 7451b6c2e892a2e6c68a647c8fca83f4d9b243e3 SHA256: 90b727aee3e11958e7c7d552c1aae769ee509a0bffc6a07db5ef125705a3ed45 SHA512: d2a3cbbf77f24966dbbe2aa2392bb3327dd16e5c1dc63023fad1292a037ad0ae574b45acfa505b66106ee31772a1d4bcd015147052f4184d51a825492230e41f Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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-armv7-dev Architecture: armhf Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 29461 Depends: libzenohc-armv7 (=1.0.2) Filename: ./1.0.2/libzenohc-armv7-dev_1.0.2_armhf.deb Size: 9058054 MD5sum: c6705d0cd513487bb028935e8a41d641 SHA1: f9247f6789e9d20941fe4811d44f551a4c469d7b SHA256: c59c224505ebdb64ca765284a311105ff2f176801703c2d0389cf36c70d430b0 SHA512: c6a82c0e40415f03cbce7fb48ef2f7ced71b0d2bce4b13e58a02e96818c46dff68f34f735b6bac7ef7739685f6b7211401a84c434183121514bcb1a8b6df6cbf Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17410 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohc-armv7_1.0.2_armhf.deb Size: 6642536 MD5sum: 6fd9c95ccb65173d38f4e02cbccbc998 SHA1: 4a9709a463146b13f7a5070ebe9b4ed8e2377f3e SHA256: f94e1b6cf2a1f6561a9a97e7d9cec54d0999b2b787d5b260545d7aece240ae1c SHA512: a268465c19d67b42592eeda0a8c8eb8f1bb86611d055c32dcc041a3f760aee334dbd73d47bcfccd7d814a8784111268a71366bee2317cc4b3456dffd5cc8636d Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37352 Depends: libzenohc (=1.0.2) Filename: ./1.0.2/libzenohc-dev_1.0.2_amd64.deb Size: 8686358 MD5sum: 952d15ae37a97192393cf21a1c614389 SHA1: 76206171caf3bc87ca5735a96a1d699de9efb3a8 SHA256: 3cb56887a90f2da7f38b3e30db324df82a1169f3bfc0b5fa3f79450fa44bbf72 SHA512: e1b45ee5780b26f7199b30048cc7af6d4a9e027091b05aa082294c38c37e5ee61ff89ae3f0c3ae4153cac60091fd93818488a3aa4b2bf7e9b2823b4be84ebab4 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37546 Depends: libzenohc (=1.0.2) Filename: ./1.0.2/libzenohc-dev_1.0.2_arm64.deb Size: 8754300 MD5sum: 013e018b07cc0f24d7b18b55eba59510 SHA1: 49a67ad83f40456d6004d897f413f255a2ff3213 SHA256: 5e6aaae230751269866f3861c1fc2f67ec60b465dab1a8811c52f673574ded3c SHA512: 5489fb867918cea8393de0b861bc471aa41b83ce42b8c53d1b3b0fcea77667c08aa14e14f0ca2fa2079dbe4d76cdef6538a9c9f7191cd124a65b8bd160850d67 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30298 Depends: libzenohc (=1.0.2) Filename: ./1.0.2/libzenohc-dev_1.0.2_armel.deb Size: 9227296 MD5sum: cdbfa4f7752a722865cfaa46761372fc SHA1: 0576146baf47712b28a5c02dac579992c92ef419 SHA256: 00bbe34508adb016194bc97aa075f89d9364b83c2744da7d6583d7ba9d05e3c3 SHA512: c623496aad5e89350e7d4203bf6e7211fe90d4db3fe970aed8a6007bf6298cdf83d79945453f62be5fbf6004dfb91583e26995f84904479290caab0055c33376 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30457 Depends: libzenohc (=1.0.2) Filename: ./1.0.2/libzenohc-dev_1.0.2_armhf.deb Size: 9326912 MD5sum: f47a0e980bafc0860d367a4d1699ec2a SHA1: b1d7e858ff7a9587ae26696953cb3da5688646f7 SHA256: bcb3de32d67ad196f748effc20a5b8689f5d5f55bc2b7f9fb32a5c197caf05eb SHA512: eaf26e0c4276ed153c778a0e99629a75385badc9ff8154e24978a758e1626dfd45b71ddcb5dceccd3de367eee2c90b3ac8d12b3b3a256ba7306d5df779d0dce0 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 33226 Depends: libzenohc-musl (=1.0.2) Filename: ./1.0.2/libzenohc-musl-dev_1.0.2_amd64.deb Size: 8448212 MD5sum: 474ae2a19b57a8205a5bde84e4f18894 SHA1: f642a50f8f6d4792d74db647459b968037540c13 SHA256: 945a217e3a40ec4b000c96e0aa2de15ba80455efbdb034ebd3aa5c3f4c96beca SHA512: 13ab1edd2b336f8933809a9cf33166c1b21b623a28b5894d46aba9c40934b4ea2a9fc1610b98421b2616e80a4cdd50e49680a94cb5d67651a195df24aa9c0428 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 35567 Depends: libzenohc-musl (=1.0.2) Filename: ./1.0.2/libzenohc-musl-dev_1.0.2_arm64.deb Size: 8499956 MD5sum: 600765f28ba4964d762dca5c9f4096a0 SHA1: 084d6c14062586de0d35e4353e8431fedcdce5d8 SHA256: 27fdd875f47ad82b63364aeab1ee21d816013f1c266eaf9baf077d0adebcf97c SHA512: 54e849809cca44c90b570a7208ab4542aad4769e37bf9fd4f26461d67796da4c959f2e9717b50a945cb5c5cae114a317bb2467059e9db635ac6c2b38a466e5ec Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17582 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohc-musl_1.0.2_amd64.deb Size: 6381084 MD5sum: 43a3bb1b2e39f683754a3ce6d340f986 SHA1: 1ab6107a5efce1021dd1a8dae7eafe4e74b50bd8 SHA256: cb6e765ce042d371c834f9598b73564f1dd4f49c5f28435b5058c4f045dab506 SHA512: 0c00167b8d7c92af28340df12067278eb554d8764aa27ff0af902bfd7fc0963304babeb23c05cc6c5f619824a2ccb46e98e6ca5f774d42be13a2555b6d9c38af Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 16272 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohc-musl_1.0.2_arm64.deb Size: 6074440 MD5sum: 92edc8cb90362cfb0650ddb6a5282dc2 SHA1: e3ba1375e73e3a8d9dff1954e335296e2465e0cb SHA256: cfd11906b5c34fa7cdda6dfd0a7d53fda33a3a882d936ad89b9778b50c9273d2 SHA512: 8685fe56be23fd360820ed4cc9d747f16f21c34e86cc2430f91bc93d860ac34cd41778b331a31de403d00166afff6312521a178cb8635c020fd753c532ecc085 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18173 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohc_1.0.2_amd64.deb Size: 6400382 MD5sum: 4cac09a9d90f81e453d25cb5d531790f SHA1: dce1a40e4cc68edf5d3999bfd29c85a34e2f9519 SHA256: 73b79b24af1f6dce03693fbeb0fbf52825e2d29d377967ed7318badb5dcf2403 SHA512: 67f216b5ec613222ff9168c8dcf292545f1426a36ef82e18c3ead57296c8ffa0eabf7901ab48ade32da699e32dc2b257a725f3b7607dd852c42bc7e4612013ed Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 16625 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohc_1.0.2_arm64.deb Size: 6126504 MD5sum: 074939359099070ace8addb995137d9d SHA1: 9a30cf33807a679482b3c9054da51115c3b07b10 SHA256: 071bde360f15f05baf538d7c1fa1ad6179a9a78ab2349748263329536e39879d SHA512: 3a616e478108cbc25f192359583a2d9fe018b6e90b7ec97f3e205b1c1e64fb5c2cfe65fa730bed11fc5d5f7c6e0f9bc1a74c3d931ac5283434f58b452f2aac61 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17808 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohc_1.0.2_armel.deb Size: 6722706 MD5sum: f615ed885d34ebe3a1f0b040c6f8f355 SHA1: b952d76828ac3471da984c8983e30d706b12af52 SHA256: 8bba1b4909b637eb68d7160cadf39ae5b85dcb24d273b718799036f5956a4f51 SHA512: 7ce69c65ea9f6198faa955bf2924a512593bbd695a8d348f8d47ae3f0159ca3f2c5656f1ec4f524a6aaad36e10f19c440432fb46f860586c5776bdcc21472e86 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17790 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohc_1.0.2_armhf.deb Size: 6785504 MD5sum: 0c3451775a5aa37eeb6fd8b1fdd597b6 SHA1: 8373d87894491254d09f3bcc1d636f2003bda5c3 SHA256: 97c2afa36a8ac6369c6581611341270e5c9e416fede30e23bae2ec8e97abfa48 SHA512: d99b0085f147e8a07ca594375041d7c6cdc600b8ba747d720a1eae3f6f4b210d354b018b0f5102452ccbcec38e5b1f64c323273b194155015a15882b9bfed31e Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 334 Filename: ./1.0.2/libzenohcpp-dev_1.0.2_all.deb Size: 43348 MD5sum: 9593f7dae99874a03146b0e0d9d9c714 SHA1: 999a83de6a218d1d994e4ba78457646b59c609ec SHA256: 5acb112bc764bcb29f4646673a40e60622649f710e9a27f0e57fd1b205a4ab9e SHA512: f91fd8f8eda67f4f71f50ed6ee4c1ccdb036c5abec7a8304f77974ecfe2b643218e2f995290403f82ee1601089ca065563b344617ca2d6a64f9115656a916834 Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1092 Depends: libzenohpico-armv6 (=1.0.2) Filename: ./1.0.2/libzenohpico-armv6-dev_1.0.2_arm.deb Size: 217284 MD5sum: efcf3edb0f37fbcc82dd631362ac410d SHA1: 66cbc50a64b868d5bed06dc9ff5a058a5ef2d3b3 SHA256: c0cbfcb3b86acca8d90744d34ecfdac649650579ec9c6385f6b48733978a93f9 SHA512: 21a5e5cdcec8c8ccbb8ec61c1f170361c7f9c94879da35f1bbb4b67a1557ffddd33e5df27119abe6b19dae61f276ceaf810ffe1edaa9746358e56a1635496c62 Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 327 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohpico-armv6_1.0.2_arm.deb Size: 131250 MD5sum: cbe077cfdb1a4cdd95654aa082343fa0 SHA1: 8ee347e4793d14c1ed841cee53ff2ed5b2f5ecd8 SHA256: a8c250f5efff673967341ab67249123728615bc312fc722d5541c27f5eac4d66 SHA512: dc08ce7ffb49a083e08d04a70f1f3f9aac25b88aa6f1c6be69eedb84502033f7f1610b94843cffdee3bc77efe648d9e7cb5ba89b4adbc324f12bbfda0cc34d90 Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1087 Depends: libzenohpico-armv7a (=1.0.2) Filename: ./1.0.2/libzenohpico-armv7a-dev_1.0.2_armhf.deb Size: 216498 MD5sum: 3803dfcd920632193a6b093a7ec8d416 SHA1: 1a30b4eb38b9fc5b63879b9b234e9cd527bbcd59 SHA256: 0791ac8a3e5968f1c83f3342b38883a21eac0b7696c5f8ca0d1bca1301bec3f6 SHA512: 154fb044cf061798f6e3723dd761dd9f6beef16662afd553ebd3ac1b552d022754e3a47b8c67200c5b340c00535893a5429af1721a41911000b3aaee0653d8f6 Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 323 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohpico-armv7a_1.0.2_armhf.deb Size: 131184 MD5sum: aa8fbceb3b6ad33684a89757f4ab4a43 SHA1: 86e3657eef340aeeec7b4b45e52a250179ce5644 SHA256: 657f9e93b7d569a0f88f3e7121039461e8583518fcc1ca8e1e2c57492642121f SHA512: f5a680fcea504f3f353bb455a9113886512d8d422281f590b196434133c0399ecbaaf8058b2b3b380f18d3770e0aa65b6fa9fbb0b3f662b699f58caee89ab085 Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1331 Depends: libzenohpico (=1.0.2) Filename: ./1.0.2/libzenohpico-dev_1.0.2_amd64.deb Size: 263618 MD5sum: 8fcae32ee5f25b88cae86a8f2399114b SHA1: 30f3a73d3b10ddd05a5b5d395d6fed714ff590f5 SHA256: 51d7e506b9d0415eccfe6cfac8c8af746c116967faed8226f1312c97bef25dac SHA512: baf33dd302103809da1b90401f36e40401b5e87a9ea6426e3440c60da2459ff57dca4df9b830785b758aac72b017278d5d38fdd6a34b07ea061045ca26e94d99 Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1091 Depends: libzenohpico (=1.0.2) Filename: ./1.0.2/libzenohpico-dev_1.0.2_arm.deb Size: 216694 MD5sum: c3a660279e05b76d8514ab3ebc14a8c4 SHA1: 64cb433112cdd2dd4fd5da42a516825d4b3112f4 SHA256: ebdf32ce94b86b14dbe9eb06c1047046f9c7a69dfa9d16cb71276a87d4e7c6e7 SHA512: 71d56b0686eb018dc7b0125a22cd67c1582ce4090330e21dc34c16330c553a65e961f8daaa35736cc06d8db9574a26099d391129f3fe9fc2321b8fb83574bcf0 Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1341 Depends: libzenohpico (=1.0.2) Filename: ./1.0.2/libzenohpico-dev_1.0.2_arm64.deb Size: 260350 MD5sum: 6061b05a6dc69e9c3849a864096459cb SHA1: 23c2d426652857c35509f355ceebe5fde3ac31e8 SHA256: 2422490043550356b826357897fcc875047743bb61dce78b48e723b0f4d52859 SHA512: c1ef3832845e6114272e32be4e192d7f82dfa30d5706eb92f4c8a1f96fe1f05d72a8d525436fd890d7149471c5b41984d78223c3eabec6860c17953424504ff3 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1088 Depends: libzenohpico (=1.0.2) Filename: ./1.0.2/libzenohpico-dev_1.0.2_armhf.deb Size: 216370 MD5sum: 32dc8f483781bc3183b6a095e7d17971 SHA1: 79573f371a1b07127c6f05b05c0318c8864729e4 SHA256: 62248c58570a95cc8699b2824c93477d3fd87fd5564e0b216862f55d4eb79e60 SHA512: 95f254142bf1dae33f0928e9f4a6106dd662f77272a41a55bfe125be7f6f3190d4608b06dc947bfc68a55550911e61ce047c27a43a9e21e56d784ef8573db8d4 Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1300 Depends: libzenohpico (=1.0.2) Filename: ./1.0.2/libzenohpico-dev_1.0.2_i386.deb Size: 285350 MD5sum: c3b530074d2c20d98b8ff99ff1120769 SHA1: 7ef85461f4589525d8dbb7f427451ef3f4421e96 SHA256: e16178fbf015ee3b74f3d19cc5742dbbc06afbdd4a10a1a8d8c5b5add779848b SHA512: f23d1d042f6f10323e4dc50de69128594735d7c0a3ec7ec1100b6893866387a12abaf07a00264bbe06583144feb3ddf3511b2793ad7c92df90ec3016d03045bb Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1233 Depends: libzenohpico (=1.0.2) Filename: ./1.0.2/libzenohpico-dev_1.0.2_mips.deb Size: 248394 MD5sum: a134cb2f9740b411ec9469002e267304 SHA1: db3467149b8be6742154502a6acca4b8b8175720 SHA256: 9cb27d0ef80a256abf7d017d0ed1a5c291def79f524afde4ff60fcbb66ae2fab SHA512: 111a18eece2540acff03d900d016cba9072329efd62c2dfd8122a2ba09c2fc678f097a21365d090873af37d76be0be2ea3a9b2a7e376b38251a8201f35faff62 Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 446 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohpico_1.0.2_amd64.deb Size: 163464 MD5sum: 982818355df97d1eb34a401bf2a9925a SHA1: b34aa943c8fdd65c4f67695c29bb0519acef842c SHA256: 85d38b9dc0ac130d530181572043295c82add77b2cb9c08086f80e4673ea912f SHA512: 66cb25618542281b067d9497aa0488127b822ee021ddf662af1429df0a74aed4999d9d57b22a7ae3a49bbc558e8cfcadb07acc60e853c71f74482f8acaa7f892 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 350 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohpico_1.0.2_arm.deb Size: 139572 MD5sum: d34b5fafbd518ab67a54179d3ee0b905 SHA1: 610fb47eb631fea5060b09d399056112a9490aa0 SHA256: 80501f523f2f003868d130b46717de59e1999c4df4d847d366f2eb5d60249177 SHA512: d1bc867bfe77d84f9b4ef237ec88dd4116562f882a8532f6b7472516b4bef95bc203416bf93cdf2042adf6a0a893b01d0b026d2b5c1dd85dc3496f661eca2eb3 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 464 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohpico_1.0.2_arm64.deb Size: 161796 MD5sum: 962c2a21334905aa2947579474b7773a SHA1: 7700e6f4f7c0f078688f0b4f64f5d33cf9a4f5e8 SHA256: ef086f8f1fe2cc366848d925b6456453b5b989ec5b6e9064a68fa09b4ff18873 SHA512: 40a28a32a9aaf2fc5e79400bb2eeeca2350eff927fa5c23732109459207f0c73edb3d458613549890fe5af5a1eb0efa209bcc6a0a27476d40072107e7b1ee9b8 Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 325 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohpico_1.0.2_armhf.deb Size: 132618 MD5sum: bea05e77c9a2f7ce29b26ad5620b802c SHA1: c5351e6f11407e254666012add04e9a33ad7bb6d SHA256: 29b893327a5c9652db8ce24c63963777561b7a7d37245117343783d9c81e529a SHA512: 44682a1c47981358a441ae77594cce18b282db10d9eacad85730dc59a39d0a49c12ba4713c28ee375b3c437247f5045763ee07d3c82fdb97c7d93df5d9af810b Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 474 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohpico_1.0.2_i386.deb Size: 185738 MD5sum: a7499ad5209e711d8bb671e46a0f8a8b SHA1: 628d7fffa8defa80bf008a8e77347eb39f955d09 SHA256: f874131e03a4b374bb2ebd59a5c3a8e8234e9848285007db726575a6dd54998e SHA512: b5b1f29ff40dbeee1570bad715e2b496e983b6d4c02d0b2bdfa948479a3d92f06f4fd59a19e657a2becda6b1963d854e1086ffd1c8af972054b7ee1dc459c6c3 Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.0.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 430 Depends: libc6 (>=2.12) Filename: ./1.0.2/libzenohpico_1.0.2_mips.deb Size: 146130 MD5sum: 999900dad80fa70c29d890e1792b3253 SHA1: d6375a0568bb66e2fd29e54f7262bf529aba175b SHA256: fa583b05e74714876cbb50e63ad0cec94394c736565d5c09ce486ccafd07d988 SHA512: d73ff9a7047e75ad442051fc116bdf5aaa215fe732bb4fd1d2fea17b5830e74f54d2a48fd210afa292ac9d1564b6d0d164b9f23cda77b741677e33e7b10eadb0 Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20839 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-filesystem_1.0.2_amd64.deb Size: 4601860 MD5sum: aad4ef4bdb2fc82a424c091f719734b5 SHA1: 49cfd427bb142a4de6257d422166616e0f0d454f SHA256: bca88b24a8eb659aa6b0675d9f34e8414eed4bd215cf4e0f6c40b575aa0cf048 SHA512: 32075ba51005ba85db433164f1ac2d00ae1f627289c306a46a390739e53fc18f55e1580a2054d131918f8a92830f7617bb4499ecd36ab638c3106b8e8fd0754d 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18939 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-filesystem_1.0.2_arm64.deb Size: 4138012 MD5sum: f0d9e4524358d8fc60b425f51703a40b SHA1: 9cb56f9a81c8e7ef04bbef72ef9804da2ac63d6a SHA256: 707fd5763cbb32f67936559472e89c0c7af93acd9ac0e6e4f4142eef308e12c8 SHA512: 997a5a158482d9ea799f94969bcd89a270e9a29af3fa7ac9d5e75fbb475345df59d1f5cabd6da1e9265d25b570fe9f944393154c8e593f7abf2dae93863b93c3 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16514 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-filesystem_1.0.2_armel.deb Size: 3909832 MD5sum: e71f8d97940b62830ac859bb25eecc8d SHA1: f7bc89d0884e55eac775906f28b83fb6c56b1adf SHA256: 1324cc16119419c0117487db9947be48f67db35387527e77bb08a441c45ef4b4 SHA512: ff7c8bf74af1859c7b5b3f116df38ae99c84c0165b84f9a202fd676511239ef3d16d291f815b486a1ebe510f849c568cbe085bd8ece791ad1a7af7f75d780585 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14629 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-filesystem_1.0.2_armhf.deb Size: 4008840 MD5sum: 0359318bae06f3838fc0bd8ba0b54c95 SHA1: 96f10fc7c01fdfc4fe2ba0209c118847875cd2c3 SHA256: 1865b9761c614f6df236ad6e0edb2d02228c37b4ae4d3dc1d56ae53813640f80 SHA512: ea3b8ed87340cb4728ff2d7bc47fa0387599df2d719184cbcb4f07e3ad8d2f1174b3afb47dabe22f38378beac79c5c3f2da5c8174a86040f9365bd668baa92e6 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15713 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-influxdb-v1_1.0.2_amd64.deb Size: 3128920 MD5sum: 6f1b2edae5691eef09df01e541cc3e38 SHA1: 5b888d39d367157e4207cb0802cf199db8e936be SHA256: 9c091c5a6512cd588e1c30011d0055394733a1ec998a62d674cdf4eabe53fb42 SHA512: b89aee59f409e24cb9847e337165964da7ae54822bc99753dbcfcf7ed043f2fd954f91c682188466ccc748cbe7873f877c2013c78ee67fcfc34ef9649ee5e96c 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14023 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-influxdb-v1_1.0.2_arm64.deb Size: 2815184 MD5sum: 338978062824fb07df33999adeba25fb SHA1: 7c3665816440ef20f7c426eb720c6209f18bc5bd SHA256: 0e29dac0a190380903f98e5801104d09bd8068c2f4be349901bacba078f7dab9 SHA512: 154a29a1a536ea64f7aaf050347c6d6aef7e6d87804b29b105ab081ab3fc1244bef900c2a58f792a46a54f69bc46b6697af1a18a885de60c39be8c7765146619 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11805 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-influxdb-v1_1.0.2_armel.deb Size: 2552680 MD5sum: e793a0b7752081e181c916bf3f9769a7 SHA1: aea7405781e61167c93e08b43c1a9cf0c4e8249f SHA256: 584f5dc760abd860ba55e75c5051d3e92eae45a6f38365224dde2da583aed9f5 SHA512: b960b17a343958a3690b61efb8fb68f06b2346e8c962230274b77a4097f639b2a5fb73b535921538841f485a416d5e24b842fb55c7c25eb8f0364d5c2f266456 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11682 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-influxdb-v1_1.0.2_armhf.deb Size: 2542424 MD5sum: 7583bf592ffbc97d4a88244c4400b38b SHA1: e345a84a583d5d9ce9e543365844f3db24d74bc5 SHA256: 7fbfb39890d7562764c83e8f2633155b7d1715eea417e6236cff4362ded6eb30 SHA512: b03d594fa79cd3e05b2c6ceb9ff12cbf568f2c9ce2c8753a466f431954eece140a14cb09bc50eaea954285379db55fa764450f4154b45880f8931307325b2800 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17302 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-influxdb-v2_1.0.2_amd64.deb Size: 3801832 MD5sum: 691c8bd897f370763412aff09bb90313 SHA1: 3a965ca660fc769fe36af92ca0eeae4646ad70ef SHA256: eb448c1733de1f4ea85228157be690a9177ecebf48c700ca9c0933845a9ad540 SHA512: 06d1f717eaa975e37ecc3d99786f73754933d9cb46c62bde31c77abe0f2ddc9f3565e2b8338b7eae2b5c8e5b1ff8f347633abaf9fa346b5bcffd7fd0c3a3132c 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16266 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-influxdb-v2_1.0.2_arm64.deb Size: 3487264 MD5sum: ab5415a89b1792e780c9430e2c974156 SHA1: add6d0aa95df4b59eab73609ca6dce3af8198f38 SHA256: 2a0027fd6609f4a917adfa1604e1427f3a3afc38c82a1cf3cda582dd1f9905a2 SHA512: acdb2b94228041ec150c53eaafb1d223b4184fd2acd951ef669ffa54b361f9ecb11b66132f86da8366fda2686100901c7690fc1c658b8219252a5a59e1fc00b9 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15595 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-influxdb-v2_1.0.2_armel.deb Size: 3470548 MD5sum: 4642046aada1876649ee9cd1b9acfe37 SHA1: 84722d678b6213fc6ab2950fe809f6f054a1fc16 SHA256: ee0d764369cd0f3be2f5d9518d392e3c508944d8f82c0c09119b4106cd825e92 SHA512: aa52d94655ed1f3397b73e87be4f611ef40830555ad35904a8eb700e1e5cce4194671e4d520061e63e1e929faecb19993cc1ad780c9a6404c0e58f5e57dd4a13 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15489 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-influxdb-v2_1.0.2_armhf.deb Size: 3514036 MD5sum: dee03c6bde3c0beab162c11f2dd1cafd SHA1: 8c995f41b54824a06e23020912fc3bf5a4cfff2f SHA256: 8ecc0e7b70f54aa89959477d389d8efaf03526d48d691269de2eee2c0f748ea1 SHA512: 9ed6a5a0c61480a9a03d5e9080217d9aaa3979aa55a7ee03f7a6f20c55e512e1f4295f822e9e0a3e87b7f673422162a3f25f8ec28fa29cf6278f982aa6666bf6 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19387 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-rocksdb_1.0.2_amd64.deb Size: 4330092 MD5sum: 78c3cb2cfaa3a231f0fe42b859898ae2 SHA1: e850a278292334837ec0d9e4b46780c9eb43ab54 SHA256: 40cc0a29b2ddd8460aabc9a82b10782579dfa94271d0ae63e3783b55eafda1e3 SHA512: 62dcf06e775c81249e4b35367164ce96c7933180a8a5159c395694057df14481d466d353379b123b77b5f318d667f39ea9892ed8fa1e005fe648242e6df295ad 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17492 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-rocksdb_1.0.2_arm64.deb Size: 3888112 MD5sum: 75c2a72c8809dbe310a06eac5de0d96d SHA1: 0fb272045aea7eef26f10e0a73f3541321da82cf SHA256: 3880e6bd725990905e16cc57b5cbaa5bf26af08a6453697732ea8104e90e49e4 SHA512: 18894e7299ec4d12fec8f7e7b759aeb5607f8a3fa2eb789acfd57beafa01c3193ceda56131296fadce853552a9579dbc549e5954830e3468048714c282b45132 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15307 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-rocksdb_1.0.2_armel.deb Size: 3696184 MD5sum: fdc343048224e22e78151b9da3ebcc47 SHA1: 774204ad242284ae56f58ae151e800cead50f752 SHA256: ddb41d10cd8406e8fc6561c33a9c25690c0af7693506052057ae05c3f96de6a1 SHA512: 3c0f30d110a3635cc03fd03b0a7de4a53ab74a612129598212ca9aeb2d5658154ee530f912d2a10455f0d6f9d107ba417beb31394bdf776643faeccdf8196e29 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13400 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-rocksdb_1.0.2_armhf.deb Size: 3795612 MD5sum: ee925a9e220014047a4dbc2d8dbc8cc5 SHA1: 04b8b2a7d0b70f2be406b5e3fe536b85fe31978c SHA256: 9a570435de597f0b017cfb32ed78480e07ac0416a3673674897b4a92e812cc51 SHA512: f2751758466bfdda772646f6488bb87e142d4f2cf37b737726a139272356cce474f9fd0483934059b61ad1cc10e9274c05a435c6258aa713130f40b608ca6f1a 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27267 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-s3_1.0.2_amd64.deb Size: 5518240 MD5sum: 0c1a63b0d91391eb8a857d0e5819a7ff SHA1: b9e3fdc37d8b0e3b389c7abb6036b40923401617 SHA256: 946865895b0f3595245a6f4ad302d802e1c64243630ebb23d3547965a66bd9a5 SHA512: 2a65547896a93c0aacd225c9a8459ea4dfee053a2be583c4046208a338651a718504b926cb5ccd1b24ba4a2e45678feb17cab5c2a399b845bf495ad9dd9bc7b7 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26544 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-s3_1.0.2_arm64.deb Size: 5230176 MD5sum: 121fda0ecfdb4cdc5cd91068c874b8cd SHA1: a27316b146777047af32dbbfb55d8e6194623cde SHA256: 525dc7d835ab12c39ae126544d91dcbe0de8dd8bb65219013a6fd51be5e57964 SHA512: 32b498ea9ccfba50e986f2b6cbd85a2e06389ab7a61f688801193790e9faa3b6d42f318d6a2436b5ef60a30102f922f01fad0d6c393c195691a77800a12b762d 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25199 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-s3_1.0.2_armel.deb Size: 5104316 MD5sum: c3acb45a7e61313ccabb99dfa61aaa8a SHA1: aa00de75a5dc15374a5c68814a70352a42b4690f SHA256: aab3c10c757de494e3bb6043a6bc92d3b0d89f0dd93107090059dec09829c6d6 SHA512: 4b928380e1ef3e545646f22717a2534f6822e779518659193178506db2f74815ffe610f6498e70a9a73a222b63c4be5be6261c62c60baa501fef929a695b9656 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24940 Depends: zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh-backend-s3_1.0.2_armhf.deb Size: 5130208 MD5sum: a2c850d69a61e4c235c81d4abd6da524 SHA1: 3777e70fa1dd633f23b530a58f4c5c6b44428d1f SHA256: 8bccd05f1158f19791592045a67dc54c9409bfa37d8ada5a1c110c1aa5b59ce6 SHA512: e2a4e373de04ba3bb875b33624f81ae47ccd8b633ed58b521622a0667bffeed3559847c752fd620e1c4bb5ae9f9b283a9c6b07bbd484a98b4ef90196144751d8 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20681 Depends: libc6 (>= 2.29) Filename: ./1.0.2/zenoh-bridge-dds_1.0.2_amd64.deb Size: 5288120 MD5sum: 15d3fb7164cf6356417d457b8f43f0ca SHA1: 69a6f1956cfd58ab06bb12113c8718d727860dbe SHA256: 4f36e6d104ab338a0caf2d90ec0128f72dc03099133ad782b553370895da732b SHA512: 8e993c37eccc94d409ee6d6633d0e2ae42b8efbbc0e3f161033e7f9e2c355867830f5942a65c82c518987ea79ceb94cec4c59a57544023d088a46286a82e150a 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18866 Depends: Filename: ./1.0.2/zenoh-bridge-dds_1.0.2_arm64.deb Size: 4778184 MD5sum: da7849cfcff0209d92becd16ee40a45e SHA1: 9683aae46d1aa85372f92a985862d742a1a41a63 SHA256: 8ff33c4c6939ece615e7c33476e0db15b91a3fd07cb2a73f759046b2155219e1 SHA512: e3615abb98ec4ec90fd27775df0c44ae6d7d6772566c37acdbf2946228bd3fd43045a3bc1a6a274d96ecb865d1ef26292ef46b865aaa12d07d0d4d288a17640a 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20041 Depends: Filename: ./1.0.2/zenoh-bridge-dds_1.0.2_armel.deb Size: 5050032 MD5sum: 63b2278402fe658c6c3d56e2bec0612b SHA1: d9156e5a44ee0c42490bea5c81cc191200ba9810 SHA256: 00e6c36f83010d9ba3c4844e0d6102a64b56f9a0db8330ecb9ade74c7750ee4b SHA512: b5cfba712bfb77d59d98266c0717bd3f05b1c91795c9d65fbec34ad7f591244787739508e6880b3d205f0ad0f1c676e6a64af219adac11468535033071547e0e 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19525 Depends: Filename: ./1.0.2/zenoh-bridge-dds_1.0.2_armhf.deb Size: 5103768 MD5sum: b812cbd7194a5e8fc69653747c28d2c8 SHA1: dc1951d9d1f1ec6dd4ae455637e1e8760380c447 SHA256: 7fbb3cff7fd2380158e28d3b6fc10dcebf251067006c8ce19fe6a56254fe9910 SHA512: e84d2a3b492f922638ffe2afd32cc6ba00a915f0610c2966ef35ccb4b5aae9b15f442f0e063f581e755d43f237b282f49c6ec8742a56ea9f8b9f9dcabcb48aa8 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20547 Depends: libc6 (>= 2.29) Filename: ./1.0.2/zenoh-bridge-mqtt_1.0.2_amd64.deb Size: 4958240 MD5sum: 5d95da9b696bf77b68b9b521a38a2210 SHA1: a9cb4e01925a0c2bef5efa0dc6285155038ebb9e SHA256: 32c2c9f20219e4df85b3e218fbbc06ab99d8c965572e110307d3491dbf954b92 SHA512: 2e9caf455e9f0b25fa74099bc33b832074b3ac645ff05d841910e7b0f7443d0cf002adbc5f2e4a095bf154d77a341234e07e38a90faa632667ffc2e4e64773d7 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18790 Depends: Filename: ./1.0.2/zenoh-bridge-mqtt_1.0.2_arm64.deb Size: 4483592 MD5sum: 4b3419d7735d7e1c49a57102b20013c5 SHA1: b0fd202cd78f2e4e5dc6a2cfb0283b8d0a3107a7 SHA256: 9c01812db7e6675fd3cdf091e8108c7e5602339dbe939cb4baec9b17d9b7643d SHA512: 76c805c8cc8a56748b516fd57cbde9712ccea42acb6c0857726a18b2e7b4ce760b4044bd9a2804074d03652d6e1f56a5be5315cc2689378fd4389b6a421b0330 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20085 Depends: Filename: ./1.0.2/zenoh-bridge-mqtt_1.0.2_armel.deb Size: 4771360 MD5sum: b73563d275116d0c82e8dfdb9f093356 SHA1: e85d1170eabb87b0e58e43ef60bcc24917e18d1c SHA256: 958a694015b6c4e135c818c037b5fa606128f42a43da6a07c07b932e1349bcda SHA512: 9c964dc06c8162d758b4ed8cea387156e89496fe777bb78c66584e47d19ee6cdb6cf4490a186cf98ee627890fcd3e841a30f059e250b0b803e367bece8063cab 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19806 Depends: Filename: ./1.0.2/zenoh-bridge-mqtt_1.0.2_armhf.deb Size: 4805820 MD5sum: ac469607c4576253e3a9af31e5342a68 SHA1: e5bc0ce48e2c84e2e998ac91690431731cd11287 SHA256: ca5d42c193556b347fccd3fad1c50993577b40cc0c16466298f118c9600e21e5 SHA512: 2bc218631ffc45d4b73df7e3287f109430436517be1c12d90c80436f7c29f01a592fb9e42a7f37eb32519c3c6c634dc6d2d952e5de0db71aa689caa3f3960df0 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-ros2dds Architecture: amd64 Version: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21243 Depends: libc6 (>= 2.29) Filename: ./1.0.2/zenoh-bridge-ros2dds_1.0.2_amd64.deb Size: 5392380 MD5sum: 5566e4873109cdfa5dc82463abc6618c SHA1: be5f2693ffe263b2d5adb65702336b74b30ad779 SHA256: 99fab037509dd7ce06c5f4230277e7d87c21acce5f4bb5affb9f2dbc69c3b80d SHA512: c352a49928ce29e76c9335e070b4f4b33c7b3cef2044c48bbe8c55ee386c0004051bf4c54057885717aec86a937bbb9e80f2aed357cc127b4c4026930d55effb 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19396 Depends: Filename: ./1.0.2/zenoh-bridge-ros2dds_1.0.2_arm64.deb Size: 4887988 MD5sum: f006230635fb295195f2caae54923ed9 SHA1: 96039377b183e4a690b3bed66a4e70b7c83e05ff SHA256: 62b6b90a187f21eca51b151ae653677b0eb5a1d20262c00f5f8c3394b9fa76df SHA512: 6e180bb76f7d5c20873f40a660fcec406ccb23c6e00ec0f2125f391d46fad889068f25b158fa5fb55a035e59baabc8a939b837ddbcae499a9d905ad5d3f98207 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20579 Depends: Filename: ./1.0.2/zenoh-bridge-ros2dds_1.0.2_armel.deb Size: 5161668 MD5sum: 516276626594a5c672c4a5d0720e68e5 SHA1: 83a321be3f27049e27ed61dcc281e425b11cae4f SHA256: 59581d21456522a35d41d60986b0642c38d12878e3fd68b499b5c10e6ea52e0a SHA512: 88c17560945af61ab2ccb695dac138a3b601f26cf83eb11d95e3bed01c0f4f3743bd58c92f2c9866916790e0f5833356ce9bf213f818759802fa03c6c7e23b9a 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20066 Depends: Filename: ./1.0.2/zenoh-bridge-ros2dds_1.0.2_armhf.deb Size: 5215744 MD5sum: 5e2d37b1f3b23f4a3a553c48434da105 SHA1: 8004db42cd61a655ad7a020e34941da4a8772351 SHA256: 0d9e22c5575a64ff1b0269b201bff674a4a2c6b7a0298730dd714003ea99deb0 SHA512: 4386dfec8f63883f99696a8f52cb01272483efd5b5d6bdea44aecb0b90de169994e5388eb1d2dd28001707faf5d671d40ef595ef2ab35637dcc97f3278d402e0 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12828 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-dds_1.0.2_amd64.deb Size: 2577084 MD5sum: 88c645f828956eaf52633c826a9d7ec4 SHA1: e26a2195a01ecc671248c9a6cacc69cb560a4161 SHA256: 2d151a0bdfa35ff9227d95fc845fe37e928c8cf55fa1cfcab29e67eaedda0928 SHA512: f7aa26d3fc2be83f695884b28b0dbabc4a851e1138e6cde7d5df7b81d0ec0a9ad2d4c18dba0186df5da8a4f585abcf5b9297705b18e68f10f2e777ed787a1cc3 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11596 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-dds_1.0.2_arm64.deb Size: 2340512 MD5sum: b0919b8289e1df5b9445d23aa9b62dc4 SHA1: 24ae0c593222a0d2b5625a61f071d79d7029e137 SHA256: c8008265ea1d897ddf2b05802302a8d1c0542189abf0eea7ca8c85cd6f25daeb SHA512: fb4f0d3d10efe84cecb737764701f019fe5ecace741fa8fc9c5a9043b3bce5a6c98089c77ccf8ab753b9790d4a97bbf865f516ba91728c2d16e3eb81cce8ada6 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9642 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-dds_1.0.2_armel.deb Size: 2187544 MD5sum: f22fcd8f21d3a78cb135672b62436dd4 SHA1: c9ba1dd9e9ef8691946434e9f5a8792c1b514041 SHA256: b3972e4041a80d5639194f7643eca6f39eedf18b2718a390eebc39609053fccf SHA512: 6c9c4079084a2f1a8e6dc7bc8dad5d36e275639840728b6babd83f58af88ed6ca14f0221d3016de41d0c3a5c41babed8f3b694d6bf1a6853bb5dfe6423cf9692 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9269 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-dds_1.0.2_armhf.deb Size: 2195152 MD5sum: e78a8ae2a46e37c0a8a505d1011b40e1 SHA1: 82c73c3080be9230dae25eb3af2a90f82cd65cec SHA256: 068d710475bad8f02dcc4f9dd838ed340c8e3f984ad15af14cb481273f08ae6a SHA512: ac89b785b4bd8276a031988bf87ad8c40399760321822c81a7361b58a52f199c050bedcc2efd710e48598304007e33952c2a35687b98fa1747573441e1a66b3c 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14065 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-mqtt_1.0.2_amd64.deb Size: 2875652 MD5sum: 693540f173f3dfedef1c65538ce9878a SHA1: b4e268f9cc2e96bffd1022584c36e25aef5178e6 SHA256: 6b5778db2ccb18ecba63b44497b00a71eccfae3714235639c23eb770608dd8e4 SHA512: 151905d1045333f278d2fad1ac02ed04a2b8e9c5ce8518d20cf64d0d1d34047bbfe9780daaff00aa5bfc464e6673082ad4521ddb513f2fd0bf9b8a18ff90d014 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12786 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-mqtt_1.0.2_arm64.deb Size: 2569872 MD5sum: 09f48077a1a78e89de30e80f6629b04b SHA1: e2025cc1de09f7fb2c1cf4259a6de94466065c47 SHA256: f7be0f779f3d6e5e7625ea736894b9bc828fb2a6c61b5eefbd9d0ff02fe8668a SHA512: ee2a2833254ced3d7490ceb1009ca4c5b42d7cc9458284a9ea194226c12df94990aa610a43d9150328d0c7e727f6dcf5b4b86c059d4387871a27674c01a9cff0 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12774 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-mqtt_1.0.2_armel.deb Size: 2637596 MD5sum: 81c8dafdac9c2f5200d09ea771d4d720 SHA1: abeb2a5ee62da1912818c9a244e61a01107ae997 SHA256: 60322b94654aa274394ad4347aec78ad6fe560bd78768b32220a46014650ab49 SHA512: 1b587cc5fa49b749d715538aafa9e898fbf37716a3263ce098f706f18774db27018afac08709e15115901f683ff74b9c92d380f647479836f5bbc514ad6384d1 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12691 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-mqtt_1.0.2_armhf.deb Size: 2679620 MD5sum: 268b897e35f8c0b3e25b8468c28b9ce7 SHA1: 21c76d5904f62267611a3d68910a2efa18c43b1c SHA256: 06b33cb7584e4c134fc097e5cbf7966b4d2666be0254350b10f8ceaa520f4fb5 SHA512: d1a503b435d9c44fd7b9b3e420046110e4d317fa08919b6f5e1be90efa7bac836d49b26d635a588f0ad8fba999b612e62c6de72e024208b50340cbd902a1e3ae 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-remote-api Architecture: amd64 Version: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15990 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-remote-api_1.0.2_amd64.deb Size: 3406352 MD5sum: ab8fd8094dc52636df47e671399628c4 SHA1: 2fd5f21e01b30cbfcfacb6214c1a5cdfe9d827e8 SHA256: 950d06db8397eaaa38bf1a1da4d38bbd31051bfe8a8fed2246aaec6578920312 SHA512: 8b6faed1e3ddc6bfdcf30cadd5fc77a9ec99695961aae84c6b775dba3579fe866cd5a710c558fbc6232166bc0b0631178e63f5e529c41f85532414649897cb90 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: arm64 Version: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14985 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-remote-api_1.0.2_arm64.deb Size: 3104400 MD5sum: 76393d102e36b3373556cb8fab775a05 SHA1: a82015de4721bc2aac3873beac7ed6062b8c1313 SHA256: 9394062dbc36b32403bdef136231f063d394094d59106d5bfa16d45b00420140 SHA512: d5858d68a620bd27c53247abd13926b59d1ad64e8758e72e0e8fcf9c928540951170665059a43d23dc1a31c9a6ad58bbe139132a8b00bf432197628a26960e45 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: armel Version: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14445 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-remote-api_1.0.2_armel.deb Size: 3069644 MD5sum: 6df2456647ad46deeeb5085ac17bcc27 SHA1: 75d0c63162a3d57ef2534d0e7477fa6fa35f5624 SHA256: 04adbce931e5be6295dac90f5e484bd4a6a68c635bf389ff0df24ce1c3ed2aaf SHA512: d60f1536cb89776aa6b1b573703e4b86ba61c2605563d95f18cfbab9160b97a600be096872dee7c20c89cf9aa96ba38d4688a0c5e49fd51a83fe8c75cdf7167b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: armhf Version: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14323 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-remote-api_1.0.2_armhf.deb Size: 3110504 MD5sum: bc8f0f2a4a67611f4572155d8903a005 SHA1: 54e5422a6c95dc28995cc58ce94a09c8b0f06360 SHA256: b5d461a10a81b7a173a776752a1633d3cc32735a766e4ea24305892922ea6fd0 SHA512: 57df122847b7f86f9dc0a3bbd96f3d4190f5deecb77ec60a988541d6b8d1e386efffdb125e49e487145a712701fcd924ab81e1979c886909d89e13eee13cf54b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-rest Architecture: amd64 Version: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10858 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-rest_1.0.2_amd64.deb Size: 2086828 MD5sum: 689b30e3a11038ac9837ba95ff93aaf5 SHA1: 7b27472892041ec4bf07bda2cbdb6c21aa4a95a8 SHA256: 3996bf8f6d6bf552e1212a8c30c7690281d4a2725f22533c64682ce9d2379297 SHA512: 6db4170ffbfc83afab60b497a61bfef989911749c202647856571b4ae8d8a8dc3117e2760c992c81cab2848fa87094256ff882ee481c2ff082b5a44aff261e89 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9856 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-rest_1.0.2_arm64.deb Size: 1910536 MD5sum: e9e659f4ff78cd94e2fdf3cf65180e4e SHA1: 4b6ffa2bc4e3e138293214c2cc079119f97a4e43 SHA256: 432cf565799bd2a23d9adf3d83d4264ab692e4e2279c302645843c95051ea45e SHA512: 0f3917b9059edfa51fe710690264210d36a0fbe158a409116ae64c5fbb1e435e836d454a85272dfb0d45e0c307ca31405853a70ee754711fa312e3ea60c7e5e8 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7978 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-rest_1.0.2_armel.deb Size: 1783292 MD5sum: f0bd5ee1b205b7a6120ed54cbf9fd6b1 SHA1: 83d2c5caee9960545ab91a6cbb4748b50f3a3750 SHA256: 7674c7d51d41b2246311feda7a8cfcadbdf71172f122697d2d3b85e44fec631d SHA512: 9f5d19b343b5453b78b4c34a8cd295ca1161316707d29d656e2ac282cdd40bcd80caeb8b4723290c25a668b8f733318e1fe3e78250a00dc1a59dc2030cd83aaa 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7881 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-rest_1.0.2_armhf.deb Size: 1769904 MD5sum: acc164965ef10309459633df48f4c0ac SHA1: 9a7eb7ea723378f952e5c26f58def59659304666 SHA256: 34ae4b54f00bdd5bbd7fe4b1e2f113f54ebdbf65dde48d88f16a57e11c7aeb4f SHA512: ecdce52f8316df58395b92e099b452a273ffdd1f7be2a0f3b3c0ab8b9a4e5f13e52e8f2ed140bb195fbe45d499aad6f87089129103c2cfb57bba62ded5f2c109 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-ros2dds Architecture: amd64 Version: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13372 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-ros2dds_1.0.2_amd64.deb Size: 2670892 MD5sum: a16e505576af601121d5f1f265dd75c1 SHA1: de945d4c0131c255367b87c7d655cfeab0a0a34b SHA256: 17c1af42ae85823299e41c2d40baa8899a36277dc4276742a5681c20ef0baa48 SHA512: 6179fe1d23944fcd4d99191c86f09af5faccafdede95a9fb003d2397911fda125417314f9a67fb59cb5882a8b1064dd724ce869f96e9a73209a72a72ededc946 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12100 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-ros2dds_1.0.2_arm64.deb Size: 2431148 MD5sum: 965865e7b3dba0b4c34e00cbe77dcf90 SHA1: c392fb344e5297078d79f9de86af886587ae071b SHA256: d3e37fa3b931d36185597f71bc4371f1afd02b9ca25969e66355e5e401c954b2 SHA512: d7110377446259038253dd25e931e745c69b53d0773df25f4f0b90212c44789f5a7c1fc60c43deb9c0e7ffa33c61d7056477c1e5a7adb93ead2731a7196b3086 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10161 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-ros2dds_1.0.2_armel.deb Size: 2290948 MD5sum: f9c2c1098f75e83a820acd76fc9de07c SHA1: c48a1620b2ec917dddff60f7d5521df112f8821c SHA256: e27c64bc4ba57cc57af135decdb8c803b7814a912a08af243fda990c8ab9c9c8 SHA512: 6f4d803ee2c281ddf2c0fe29e1e2e97bc143358a64c1a495546b39a02591b569f75189cb8bef810d003218ec94a94fb60633911e9d106c184846faf30f521b33 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9784 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-ros2dds_1.0.2_armhf.deb Size: 2298824 MD5sum: d9ad4840dad816864e48ef4e42a48e08 SHA1: b30cf62028ba1808d165bde4ec5d2da24212b693 SHA256: 44a3ae08e8868a8f7491c9c674f994de91b66ff50eaf4ed22e017d18d24832cd SHA512: edb874baa5487bd89540a6040ee8e0b3496ff018da60cc5124abe40a0ee5287d94fd73fced4949b0bbab991226e78362a1be1fa1e3306f9f969a2ee4dd2386b0 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10587 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-storage-manager_1.0.2_amd64.deb Size: 1980828 MD5sum: 19bee65583ba52138ffc537366f1483d SHA1: c78e2a059c66b68a03838acaa354e09810581ee3 SHA256: 5867f760b12f8e5ae6544a64f23f43608aec50307a8eb25521237212dd02bf6b SHA512: 3816673445a690fe0c1682273a14d98bcaa403ed822376e5c3cea47b697956e65f9e2042be4b5bf920e1e9abc496292c4410a4c9d9bdaac48aab16ad6627f509 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9552 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-storage-manager_1.0.2_arm64.deb Size: 1807712 MD5sum: 71d8313631494a94ab0ec8950af97cb5 SHA1: cf194857d7de5463b1deaee93424df73639cc651 SHA256: 1d3b6173ed7f78da3a584117a6f62051023a79293f228e9f93d7e545b40f3e82 SHA512: 65fc0832f5bc5d64c0e4fda9cae271be9edaef867b6012b758b46642ad6c5f01305f819d9ec241533190425df4a842c5607147bdb12b3705428d70eeca2643bd 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7736 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-storage-manager_1.0.2_armel.deb Size: 1698084 MD5sum: 59a2601cb766d5d2968f6068acfd9600 SHA1: dc896c226d7bbaf26f670aed4097001e6314a9c1 SHA256: f21d7887406274295ec5be488421e290710e5b3b450ebc4d2598b2211eab3ca6 SHA512: 67912c02e982a88a4a39dfdf1e1e860561b7b2f5cb85d9cdbf191e1881ce62d9c4940bb9b6231d423ac23057f9bd0f2735914234a5a69f16f8fa8d0c60db5ac3 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7627 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-storage-manager_1.0.2_armhf.deb Size: 1684656 MD5sum: 3788d62d4a70881ef49ec6852d087e8d SHA1: c0fc2294ff3a78e283bad1b0d2bb9e1efe88c502 SHA256: cf5246c0c2ad1fe69979569412db2f573ea3e4afab9a5fde8c2692a885a6794e SHA512: b00bc35815b24475cbc900e80ba8b74a712c095a14c0906b0c3eb1d2dc5136a99b68e0180905337966bda563a74596b09836a6d4c4a44bf96c667e4f1dd23f1b 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13290 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-webserver_1.0.2_amd64.deb Size: 2518244 MD5sum: b94326d99220cd9a5754115ff5e2f00e SHA1: cc9a3d5aa96af372417e190e9027490eb9d3c615 SHA256: 84d5099d9a0c133b3e1ef40bb0810065fb1ea6b3797a19854bc4ac65b025f8ff SHA512: 25664cd57b7093baf80777984df1c98cbb3a6a19eec15afc3e14b644a89c4914217237d4d58f36ff2252f31b54124981f9c8a0ee91dd8b49236125a4ab416d9c 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12456 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-webserver_1.0.2_arm64.deb Size: 2348360 MD5sum: 625c4663a6eae599fceacc07e1891745 SHA1: ca2e5bb79405cffa448de1ffb79c3a1b34dbd46f SHA256: 724158be300119ff43bbf1f7cd7ef7d1a74f9ede999455dc7c503db2e4613762 SHA512: 8855fd3a0ee87b61579a9550013f2f3f7a4f6fda439746f57766f68db894e8d5781a58682b710c25772d4212e5f4ad3d6d459827c269cc786d0ea83fad9f482a 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10210 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-webserver_1.0.2_armel.deb Size: 2146536 MD5sum: 78d186e3fa3dfe09211b91676f490fa1 SHA1: ee147dc911a7fefeda875a15da7862db63e5e0af SHA256: d0dbb543f5f91fe2c7338a0fc265e2442bad24ad31ff3b6d857f345a0c72c0d9 SHA512: f367a22867ccbf071eb43f28efe6518cafc96e5ab533aaecfd95268ef81c294777f9d88a76a9f76b4faf2a7e1216afed57dc271f12ae88cdc0e00e489fe6d12b 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10079 Depends: zenohd (=1.0.2) Filename: ./1.0.2/zenoh-plugin-webserver_1.0.2_armhf.deb Size: 2133920 MD5sum: 6302939dbe2317bed5b40b7495137251 SHA1: 9d81386c769686e518d55da5200bb154dba0cac8 SHA256: a2e840122cdaad1cbb1458e263df3560b2a9aa6544a9912caed872d1b8183688 SHA512: 737753ed7dbde4d207bafd5c8866dc1747fbc282453324db401844ca3f7b32497cea3dd01145fa9f5793cfc5f9ec33c34432704a3f8401e37b6ddf89984ee6aa 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.2), zenohd (=1.0.2), zenoh-plugin-rest (=1.0.2) Filename: ./1.0.2/zenoh_1.0.2_amd64.deb Size: 17568 MD5sum: 5d8bccf54b156464e2e0821cd3e43561 SHA1: de1c715c4fd8a5f75dfd9b711b4333863f9f4f78 SHA256: b4bc97e5708b38530fc34ff774dc2f13caf3180f6e577bce1ee74a3197f687f4 SHA512: 855c204e1d68766623fce16876035b8b94b75fe266f33f947dda67cf78c9c61e2f500b7f27c6c8c76a80486a8945a53ee92d353a886124cbb308b61c579f7113 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.2), zenoh-plugin-rest (=1.0.2), zenoh-plugin-storage-manager (=1.0.2) Filename: ./1.0.2/zenoh_1.0.2_arm64.deb Size: 17568 MD5sum: 478163082a99976a3582fd64baa948c9 SHA1: 195374f3b2e1ade19b9c3f75e6a9f8f7a316f83a SHA256: ba34bd3a796c0367a16d64052d2a7feefcbd3c531f3fac0faa2ad6f2c01b853a SHA512: 80d92b35f52573338af741b2e15eec7aad23546c0643d679b3cba4f310e3dde9bb12fe178c0f127c4b6844b1cf8002eba2515c734dd917dce8460301d36c68a5 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.2), zenoh-plugin-storage-manager (=1.0.2), zenohd (=1.0.2) Filename: ./1.0.2/zenoh_1.0.2_armel.deb Size: 17568 MD5sum: 32fd6917709a2db3a4d1a0881198d191 SHA1: 4083433d6f3ef88f53a6148de6eeb9a35c434d2e SHA256: db16fccf328f0c2257bb508790de9c494d988a65efaaa436aa019b7c933577b4 SHA512: 5719d7b1543b0ee3d2061be23447988c21ea940a8f791ff9973c83dc8609e3ebf7e71ccb62b0866b27d2853cd3f0f06ddac386bcee6444d08e8a46da8ea9eb86 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.2), zenoh-plugin-rest (=1.0.2), zenohd (=1.0.2) Filename: ./1.0.2/zenoh_1.0.2_armhf.deb Size: 17568 MD5sum: b6a49cb3977ba3f193d05cf0ce923a5d SHA1: c68473e48cd8637687ab5d27fb275bc44bc4dbf5 SHA256: 81f7aed54677bcf8355c2ef08fddd638ffdf9286f55a843d7e233a2544d5f2f6 SHA512: f93b477c8145db52574b6391c08a8ecc28a8337d2d4466a983b90bdf54069ace9f275284aafb002b6855b4094192e4dc2dabc22871085b85a770503994d4f6e3 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18069 Depends: libc6 (>= 2.29) Filename: ./1.0.2/zenohd_1.0.2_amd64.deb Size: 4430988 MD5sum: 7389670c16e1435e482dc844f9d0cc47 SHA1: 1d2b039c208114feab39cf4ff49b5a12a06f29ed SHA256: 101f4720bf3c28f931308e4f65e942223068c1f20512d80987646708d335bf23 SHA512: 53b7f6f3e3d70cdc6e7841c8520c63b6ec035cdb682a7e0f2d42176b35f28fa18be2b86f56d7de15379e3f955f81eb98b65bf31c98f15b6b95f8b93a9885f84e Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16211 Depends: Filename: ./1.0.2/zenohd_1.0.2_arm64.deb Size: 3990788 MD5sum: 5f7222fe79610be03ae0b1ed683678ef SHA1: 903d109ac5cb8c3c38cb180d92566cfc6e6a9d61 SHA256: b8681ee910c2e76aa8ff2b460df99fdcacf5a7ae85c2d8832ce80c11400f2337 SHA512: 1a3d4d486b4cadb1857e0ffa6a976ef3dd817eb1f3874d8f5f8c423d6711404fcea32d645b8052f85057228ea6f2b8ee831764957d91260c40f201cf926bc52a Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17573 Depends: Filename: ./1.0.2/zenohd_1.0.2_armel.deb Size: 4332812 MD5sum: fd36d3e256ef492c1cba88d7eb4ffdd1 SHA1: 1766235f8fa8fce03a12207fc3707efdc9e0a00a SHA256: 043711253c16d24ff575cab5540fc6b29514a09ee4f693f5f77aa9506ab90225 SHA512: 0f41343e9dc658dc1b0cb1bf5e4e5f476605129d434847bbc0762f0b8ae9905943c973b34f947122b54abea188c051bd9af8ed9d2af648e73a4721b30239ee90 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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: 1.0.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17354 Depends: Filename: ./1.0.2/zenohd_1.0.2_armhf.deb Size: 4393748 MD5sum: 01c9d4031f09c2ec37018490c15f107a SHA1: 9b5c34239d7abe0dac310c405fe025f16225f34b SHA256: 9c29cc7bd5ffb33ad6878521598d2f316bf8832b537648bc5d1a7addc7799e47 SHA512: 196dcb5bdff320b15b7fb24d31878a50ee828ba05b1f0f625108438e315f55d9b463b9308ad0719be317ae80f57ac3be9d060d8205e44beb1d522b5e2500e7d6 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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-armv7-dev Architecture: armhf Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 29619 Depends: libzenohc-armv7 (=1.0.3) Filename: ./1.0.3/libzenohc-armv7-dev_1.0.3_armhf.deb Size: 9097954 MD5sum: 7bab28be866c33bc999afb80373db001 SHA1: 6ef8bed5f89addeab7e13e37053e5c08c0b842f8 SHA256: bbe460f38e023401923bea210b72c53891b1245c770544b7a9c7b053c48bf522 SHA512: e4405fecd8c385aea6d3d5049ff7e6bb7b2547a4266fdf1acdf76014b75309997a57a54d11c2ecf4851841fe99e69d1e3cae51235fa95d3a75b0f335a311c8ad Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17516 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohc-armv7_1.0.3_armhf.deb Size: 6677380 MD5sum: 23d7a12aab84b950fa93be23c84d786e SHA1: 0265ecd88b2d78de1ec32030021d66a77ea7f7e5 SHA256: c6767e2abf6e30446c3573a14182d73200e32491f95bc338365444b7ece6464c SHA512: 8dc0aa29a74dd1fb82c2baea98903388c712e185b5994e6d5138650844ee1157f8e214e8d7cef0afa4193fe0702c5c6e55f2d484f330d2cf6276f54d7ce567aa Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37534 Depends: libzenohc (=1.0.3) Filename: ./1.0.3/libzenohc-dev_1.0.3_amd64.deb Size: 8724594 MD5sum: 1080172eaf47f45eae01a918680586ee SHA1: def2bbdd92c44b2554a39d84a7e12e9d482ed571 SHA256: 356bcbe827faa4f87341f74400591e803d2484a0bcd472072bbdf5d2c1d39f49 SHA512: a7ba1d39161b8e331a73b73c02ddb12c8acc7b324b98e6098ceef2860a7aa1b5259c9763abce1e418db5d76df50ccdd685da1437f51cf27a9f679660000f9d4f Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37791 Depends: libzenohc (=1.0.3) Filename: ./1.0.3/libzenohc-dev_1.0.3_arm64.deb Size: 8798612 MD5sum: eb0f52eebfe33f4992678b0ae569ddfd SHA1: 0f8865d9e9c3791c9796ed08cd72295f0ecbaebb SHA256: ad3b987e1f0203cec761d25dd8dcd8cff59bd06e716bb53b7618864fdd37a879 SHA512: d15ddd267e0fd9afd65fb0190320005ee6e01b392c6f54a474622499fd788fc5acb16cfc670caa6e2df53a94df4ecadeb60e8272b248ce6909f2deb52a4e6de4 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30460 Depends: libzenohc (=1.0.3) Filename: ./1.0.3/libzenohc-dev_1.0.3_armel.deb Size: 9273598 MD5sum: 952155865de2acdf9685a4f29e0ce6c0 SHA1: 8c11acd3441c828d3ec8333dd485899dbc898593 SHA256: c882d741e97e2143070f1d3fa4b4cb2ea4b5fe1e2d9ecadbf8a5b94e36d92921 SHA512: eae634ab4fe817214dc78dd42efce889a9c6d6b2d693f1e8f6fd23d981e085bf6c9191447296a5e90c951ac990784014f69f0290c5ea39f59cc14148d6692801 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30617 Depends: libzenohc (=1.0.3) Filename: ./1.0.3/libzenohc-dev_1.0.3_armhf.deb Size: 9371420 MD5sum: 2f084deab884165191e9c3328cc24d5e SHA1: ee202dc7396ef7c88e0ecffa37ed582171656fbd SHA256: 2f6077f789813b7c8a7bbf0de0bb5f50f0b9ce81726ea1485ca3239d9d8d194e SHA512: 9b14b035ef0ef1a19f89f90f61f18f99bd75ad461a7745d51c340b41604a3ccf8ea601b591f78da4169ca49fbc6bb613f4da7c2425345cdd45d17b8deddbeffc Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 33407 Depends: libzenohc-musl (=1.0.3) Filename: ./1.0.3/libzenohc-musl-dev_1.0.3_amd64.deb Size: 8478840 MD5sum: b8775397d3988756e6fec27c0cfdfc09 SHA1: 71767790623fae99e1e0bdd3b273a43104e0b465 SHA256: b62a4cb4968ad7acc31b400655da465f5775c65d5aed3dbe6def275ab19ff79a SHA512: 0ec7b02309d82de52140dc592f432fa62327ff3b9c8b95720ed2e34fbf63472500b8749dd94e66baaec5a325a39f3e4bd86753209f5a9468ab474b40d6682697 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 35809 Depends: libzenohc-musl (=1.0.3) Filename: ./1.0.3/libzenohc-musl-dev_1.0.3_arm64.deb Size: 8547966 MD5sum: e368e39bf2dcc2a26562fc968c07d7bb SHA1: 514e963c722502a1b91fc5db6fc7b9810c695e14 SHA256: 6eecf85b3562121f76cbb6f84be7450c9449e9d3b6330447b58a5582874f5432 SHA512: a2010d6a2f33771e8939410955e591316a0bbb81f11c26d3aa34743234adf64920e1aa351810ba6260447c3c0730824de9686b3b011345e12199bc185c9bf923 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17674 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohc-musl_1.0.3_amd64.deb Size: 6414616 MD5sum: e98f03fe65761134ba711843e1590028 SHA1: 2b648532398184e5e7a7e0e403713b54877ea632 SHA256: d533d1a75e45d815f86bb7ac714ff6cae8e821e7744ae6109f66d6b94d4ece5d SHA512: a19cff5122be3d499db4f187bdf716ffbfff99786af848f87fa02df10914a5d990fb0b598b6dc5635cd1f33d2d3a1938220bedd2efa609c0635d993187b9fd2f Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 16373 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohc-musl_1.0.3_arm64.deb Size: 6108844 MD5sum: cf15ca78bbe5509a3a6db8644a3858c2 SHA1: 46ae313951d5a54ac40169e9a814e85a2c1a8622 SHA256: 13284c95635d64b93a9872ba927520b0f7ad44eefbaceabb72f0b80d75211ed1 SHA512: 8cf7813fb6684f43fe6c9ef37211c3295b855376391417fc2d29e603c48bc8eec509c9e5c863f9afaed1d566039fa1434fdfc2fb7610f1eb8ca803922b2af38f Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18256 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohc_1.0.3_amd64.deb Size: 6432318 MD5sum: bbf93dafdb07bdeb4669bfdc350b16fa SHA1: 413351eec45fba4329a578f2e94cc5401fe906ea SHA256: 6b74e2f23228840b915f00767875aa167bdd4730ea16a386fd5f660ea17052e3 SHA512: b915de26d99791f744a00d2dda07d9376636a5fef3a2453b29e902c9fe6da402f1a0b1485b0c197f97d18e42456646b478e4973f9849b8242a51f1565de4791e Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 16718 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohc_1.0.3_arm64.deb Size: 6161744 MD5sum: 71412b0e107c595a062e1107d2822f4d SHA1: 69c4ab5e9faea1d25ef77b1bb36eea5f39776015 SHA256: ed3629fe6c48bf08432fcbaaeaf3c6f08b6820b928b20b185c66aafabd4b883c SHA512: 64714163a9676b29afbeb3815288b3018bd7aeb017c0eef4a2e8835190eb2bb5204f10146def46388bdf1ba47e7a1813ce38fd39464260e70284af94ad0b3e7a Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17916 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohc_1.0.3_armel.deb Size: 6762300 MD5sum: bdb78e22438ab8c8c406d97a98e98db6 SHA1: 6188c1454bbc2bedf27671786b60922f40b55424 SHA256: f0bbf4973e79038ed512e3a9903006f36aed41ed70af968938b322c1fca70299 SHA512: 4886699ce348a056db35396cebb76050577fd6bd39ca660e7581e06d998a08ff822d7da26925fd6fe81a2867f4ae00d80e17b00afc59fd65788123e4c0512dd0 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17898 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohc_1.0.3_armhf.deb Size: 6826846 MD5sum: 43019a3d464b0243d5a649a9478c0c90 SHA1: 9e975b9361c54cab4e0ece4684472c897b3c257f SHA256: e92796303690b76c3f4e4e7affb2cad4027a23f09ba014e4cd6aa3f3431c0bd5 SHA512: 045a02dd0144335ee4e7231811dd57ff8c424c66119e9e0990d129d3a36d487d3642ce04b1f7d9cdabf3f3512c8bbb74e5fd8acc4ec1c66dfa3f0f49dad4a91e Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 355 Filename: ./1.0.3/libzenohcpp-dev_1.0.3_all.deb Size: 46348 MD5sum: 96bece793bdb687d3fbe4bbb094c370b SHA1: 8742da905f53cf91387fe4aca5e163fe35772890 SHA256: 20d14b52c9524e4193e80a2d78411dcc5abb03a6b74c1c24026efa242d818fd7 SHA512: dd10acd9a866c2c3f97f183cc90f2c137f11c3187e647cccdeed972c1affa0d3c1cc3618043630823033aa6f3a51587afc8df5777a53d306fb8a9dca943c4a53 Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1114 Depends: libzenohpico-armv6 (=1.0.3) Filename: ./1.0.3/libzenohpico-armv6-dev_1.0.3_arm.deb Size: 221006 MD5sum: e7d7feab90a2d62d53b46a184889fe78 SHA1: 2bb1f230584ff3f299cdc008b81b273295b5dc36 SHA256: 82b266cbfba9b13dfca344a8b285b00093ce08ddf12610d1a03f3b8c92d80ed0 SHA512: fd7d2108ed00dc4bc04e82e66b1269bd013a690071016cae6fd78fe1877c7565fd0b3e174f8f83fe6d135958d6b1cf695071f21cfe7c7427fc5b8f86822bd0d5 Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 328 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohpico-armv6_1.0.3_arm.deb Size: 132368 MD5sum: 0d821a61a90a3167bcb93def6d6f539f SHA1: 58babee71a6e50873c39cd423d2d76900f254fa1 SHA256: c16c5d62e565968407b15b58dd984806e3107992222ff4f6588d21389222faf6 SHA512: ce90a6059c71def27e2b5276db820b990cdad0f2a1d11597fa1029387d27d099b4db9b5d3e7cab3d5dff03d2522c7fc3f76e585e4601bc207cd95492f68c9a8a Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1108 Depends: libzenohpico-armv7a (=1.0.3) Filename: ./1.0.3/libzenohpico-armv7a-dev_1.0.3_armhf.deb Size: 220154 MD5sum: 0f53da54e78b8d6c13ac12c0b4c26587 SHA1: 63377ec781ecab8bd12cae0d20404ade1ac673e4 SHA256: ac0d682b7335431cf7d1d5434f3e634af49e0902e6a7583f28a8f7ba2dafe66b SHA512: d960144a31949405b3aeeb528544e697339109792343b28e3f352b5128062a5d0c9b0746f7d7c90cbd9017f59e175f130ce1f559d6367fff1bf462c6b6750a38 Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 328 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohpico-armv7a_1.0.3_armhf.deb Size: 132290 MD5sum: 2ef9c0d12183aa7eddd21129d4c63839 SHA1: ef9036f9218e9d9d2d4986c7c6d2c3d985bc779d SHA256: 5e1e73abf5387d1e8365c21e6e7ef78aa492bf3b78365bedec8f610ebb0c5715 SHA512: d69fd6763ffe35af098c9402c3a0c71b8a53edb7115fe5987f18a8cb64cc68a519af15c9da3c8f72b96e816d361e9ed7c0022a4e5ebb978b84efdc179cbf84bc Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1354 Depends: libzenohpico (=1.0.3) Filename: ./1.0.3/libzenohpico-dev_1.0.3_amd64.deb Size: 267456 MD5sum: 94732f4a310d2b4403da45fe32bdf739 SHA1: d7824c294b15a24b83017959e012b2382110a82f SHA256: cb3f45c750186b5d140c51a5e66eb2b68bf8fca0f2882dff8f6942195f75e3d4 SHA512: 5d2dae973c12041bd18440aac7da3fd863aa99ae8826a4ab7e301adf218fddaddbb931be85a0ff5a935422cf599783a46f7263d1f7911140e3a71ddd71105bd3 Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1113 Depends: libzenohpico (=1.0.3) Filename: ./1.0.3/libzenohpico-dev_1.0.3_arm.deb Size: 220342 MD5sum: 33c4faa6f2f0561e1b94547dbab1232f SHA1: 785d4a0a91bdb7ec32316ce1ba12051d18bd4ad1 SHA256: 0744596790770e5a367193be831ce9b1c0927160541f167328ead375a7abad60 SHA512: 90bfc45d92e6d0e572c8aa4f7b04c68e1925fbc5caa8bc72df0845da1b1e3e332fd6744dce0b1f6e086b2de74cbc2927b3fc033881d3f0ab87d606e532a7d8e1 Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1365 Depends: libzenohpico (=1.0.3) Filename: ./1.0.3/libzenohpico-dev_1.0.3_arm64.deb Size: 264322 MD5sum: fae795b64aa75d6dea5256d8334f847d SHA1: 7af8e646d0688634dcb694a5c6fad93a3c30eec4 SHA256: 6dd942e84034e670e77ee19f9040717a51ed17d23d05f0b6f4c2a4461b208684 SHA512: 55c1f65cdb9ba16bf2f096085038bbb008a4593dcb05cc51784c9345c5dab593e01f4ddc4690132c473979b783408043be95c1233c055e66a57227d106cb2207 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1110 Depends: libzenohpico (=1.0.3) Filename: ./1.0.3/libzenohpico-dev_1.0.3_armhf.deb Size: 220134 MD5sum: 4e68de3e26bed1305674f7464fac7347 SHA1: 68cf7876e7aec86c4d4449cefc08fe4caa9661a5 SHA256: bdb77ac6aa2260affc1c897ae066a8d3783e8d9ec5b0f609d33a4fea2006781f SHA512: 91251102aafc767fbe00f58142d292c1b90b7571cc23d0921ce25c90fa3fc502068e03f757f26285ecaf4fc2371a0dac35545ab86f5fcfe4a01ae44bca0550b2 Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1322 Depends: libzenohpico (=1.0.3) Filename: ./1.0.3/libzenohpico-dev_1.0.3_i386.deb Size: 288786 MD5sum: 4907ee328ff6c608e1e6a9178e4e5385 SHA1: 5aa0500b38cef4497eed8f6c76c93577a5e07552 SHA256: b0c3f400071e4345e9aa86d79f96d8f64e11f4fcc64af91a08ee4e958322e405 SHA512: 1218b869e105ec22984ee5d0d4c8d3122c08013e13e2eca75d1c44124922562ec21e1921a178b2fe028b91e21372d9f35f73b953ccf41aa48b75e3a4723e7c7f Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1257 Depends: libzenohpico (=1.0.3) Filename: ./1.0.3/libzenohpico-dev_1.0.3_mips.deb Size: 252218 MD5sum: 9529f0e2e078a0dd2ac02a557aae273f SHA1: 81a7fcd4cf5e7c67eb6f12c430046f3defdbd378 SHA256: 67b741d73da027ba8af6019cc4f1142b8f50522a706515aea60c0474ab795f65 SHA512: d6da0bddd2616347e7f73304f5afd91c098a2d818dc36ed5ba58d8fc6a74ff24fe8431c49cfc37c92007b2d8ee4543d0b9af1e90718689caf295da5e5004b995 Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 455 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohpico_1.0.3_amd64.deb Size: 164888 MD5sum: aded245763fd3913ade17268900b1327 SHA1: 270965963ac51230e202818a2597ca5db595d7e1 SHA256: caddaedcdb7385c42f4cfcea5c1969827fe4cc6fc02b725c67004a87f2b6408b SHA512: 3810a05df141990a0229a7e5aaa95ff31d42edde7e77f8005985ecc01647798ce1ae108b291b55a37174f8913a3dd7580a85eaa8b1e0340f6c6d035036d3d9a4 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 355 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohpico_1.0.3_arm.deb Size: 140654 MD5sum: 29ad7ad9c6e55e6f5f47f11ac6b5e847 SHA1: daf3bb94cdb6f579b93918d0403d9e6d637ac250 SHA256: e549f8f441250fb2d699ce5ab737712127534012b416b8dfa3c506e695c27fe5 SHA512: 3d91bcb6281ecc3768ca0bfe0a9dc97d8a7a4da4654355fe357d0a4664fabc57e87f3a451d00c73d5255f8ea39cf8eb8e2712f862037a3fb76a382af8222345c Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 465 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohpico_1.0.3_arm64.deb Size: 162768 MD5sum: d30d0bb354645c26eee650340dd3fbff SHA1: 6bd8d06d6338fb5d3db3fa5b0c1afbafb98d30a3 SHA256: bb7f47826b3fa4858664ca860ef878eb82494b4f2d1ca68aa6cc37670f686b77 SHA512: 42e98a7b8b8cb93ad8271252ebc0f8373906a173525896b489d58e04ca4377c1bbaadcfb9e018ddbf2f26e1af618426585c930e3d8dd75d2dad9cadb23fd0481 Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 330 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohpico_1.0.3_armhf.deb Size: 133734 MD5sum: 1224846de4a9107b13a8c7aacab2aef3 SHA1: 509fc894416483fccf80d0563527090af4a14a03 SHA256: a27341c9a5e2626af49718bd40acc59b4c5dfb54b3007439636691e8af564a39 SHA512: 7ea800c73711d9233874ee33fa391a3e2236b8e88dd82b1e9aa742552879fc700dec59a5eab971c447d0b6a1827f5973bd864e8392bd68d210df07a267df6bfa Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 474 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohpico_1.0.3_i386.deb Size: 186784 MD5sum: bc77db429ad92d3264aadbadb54f99d8 SHA1: 8fbcbc657118dcfa7dbfb5ab44b50607b774ed47 SHA256: ac1f70b51d2c00112844eec61f63a69e82669ba086bfb18148ac794b22573d4d SHA512: 6d9040e7379f218f59497e72cad3bad1a862b1d781b88a8fe99722ea8e70dddd7d337bf9819b4c35fbfcf49b9e184531a9dd3800024ca9259044c522e74ba418 Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.0.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 432 Depends: libc6 (>=2.12) Filename: ./1.0.3/libzenohpico_1.0.3_mips.deb Size: 147166 MD5sum: abd9523449a2bdcb84770114c6fc220f SHA1: c8b6ac2c95e2bb0fb157c31194f70dca2e06ec7a SHA256: 421a8c3ab228737e211b72cc1118b57dc962f8f35b0e19e0cbd70d737541079f SHA512: 70cd5c9a04076cb0e0aa6c614650ff0e087dde6b1f4f7687a6562d6f18d3fcaac1339a29d22a6ba1ff9cc0ce7ea7e3acf370763c2a25fbbaf161868691b46eca Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20839 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-filesystem_1.0.3_amd64.deb Size: 4600936 MD5sum: 601e91b6f16669623d43c56e3b469eda SHA1: c0870450aeb49eaea68b7caead9124b77bc247e7 SHA256: 12f9b8419439c7d4dc47d6de5c61143ec970b26a0da2caaa69e45f4b1ba96887 SHA512: b19393c29b3ea65f0b5eca6f5b2f2084116328a13c2d477f3e3272fa19bad55ba13e9e29fd485eea3acf1c62870db126ba822e537ea732e19c6502f71480bce0 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18940 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-filesystem_1.0.3_arm64.deb Size: 4140332 MD5sum: 4f1edb691f9d4726a80a43505df7ba18 SHA1: fb75e4d1036fea01babb79825520fedfc02a17df SHA256: a7cb8867e1557c1b63319b78003ec60580422bb404e2f0c458e13e5e982b1d52 SHA512: d425046d6032480db34d76073d6c01e33dab95ff2da069048be54746d1b831303b45170ad85f7c96520c924602e7ee6188ad94d541af195268ce08f249ee49ed 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16514 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-filesystem_1.0.3_armel.deb Size: 3914384 MD5sum: fdefb3ea7aecbabcbec276299c9570a1 SHA1: 2f4d823caf5b7a94047babad4c7048be49dda45d SHA256: ae29e670844f641a630b1452c5a5360ebbe7c890a44e7646d4fc20ec5705570e SHA512: 05062ae8b72aea60795657fbd04b8c82a31feadc435857241237edf66f70c102dfdfa7de084a807ec4f8ca00b16b4f9d1402941127e839832cb8d6111a89ee61 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14629 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-filesystem_1.0.3_armhf.deb Size: 4008504 MD5sum: b1a9dbaa093a0835ba6ab9e8c5fd8324 SHA1: 76253346d93b5f1c6dcb4a723848e635d61d6478 SHA256: 3c5f9f2af78e0d923e1574b5922ce7c12549dee0c9e8dd8bd7958e7fd9e13d7d SHA512: cc8265da5292e00a5b4263b0a64f7f7d8bd1b904857ef68ce2b75cb9c34928ba11062eb499b515a83ffafc60e8566a82ec069b19e8fcb725174aa6349cbe8e44 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15713 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-influxdb-v1_1.0.3_amd64.deb Size: 3130052 MD5sum: a808a66080a5c544d33545aa8c7ab79c SHA1: da719dfcad3c10c829fab519d651dcc73c04b0ec SHA256: 970de1393cd47ebde6213eacbea8f601a5c1c142a69cf9b9bebca5f2ea6565d1 SHA512: 01154e194adf0f13f477c2e13210b8a9f48eb5eb830cebf0210fe4ca6e9b176f2b26ff11406becfd8c7bbe24f2ccb808663cf0cb4d2bcb0cdb3976174cffdc6c 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14041 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-influxdb-v1_1.0.3_arm64.deb Size: 2814160 MD5sum: 1530f43737a73aaee4c1ce8e1d7ebad3 SHA1: 15d49fa1305c49101fe89e6a34ab35192cfe5c20 SHA256: 904250152f7bf96e6a6ba26484e923417c5ebed8752185496871396c3af93efc SHA512: 9c990356b4f1223363041a780e9054e28bd40f1263f5b3c878d7b6b6150b78370906107ad3ad7d15132a38cae37bacbb6cd9eed5bf573148f7db4ecc913ee41a 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11805 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-influxdb-v1_1.0.3_armel.deb Size: 2549332 MD5sum: 872627573dca773584e43e67cd55941c SHA1: 0e99c9cad898fa3bbd923e1a92565a3b3faa61dd SHA256: 913f74abea05e89ba1f4e23c462db733deafac6fb518b89ab9fac70c11c28986 SHA512: bf6618be287d271576368616e6b5ee9c4a7b2dba3d9f7b6e55692ceadcc8797325a1e290515143b90dcafebce383bd4b0f584381dc4d596496d10508a3ed6d75 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11682 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-influxdb-v1_1.0.3_armhf.deb Size: 2542104 MD5sum: 8e1b10567010494028b24226b68ca9dd SHA1: 5237e4f9eee8dfa31bdaf22581a8f019250a5481 SHA256: 51a25c161859f27340b0eb164ccd1847df7a3523f8f25554fd784fc2d028be67 SHA512: 6241ff2d9f2fe376af17c782c15e495deb9f7a0488cccec9dac12a93951652dbc8ce84912ee799a41d5c34dad3148ca4f633ff078c058462f369d1751f68dab8 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17304 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-influxdb-v2_1.0.3_amd64.deb Size: 3803932 MD5sum: 5daf3555d231211a78f53bd44f20d9d9 SHA1: 6b2159cf569344ab558dc9d87e53e877f49e57ed SHA256: 8893f3310de02abb6a0e32a284fc6016e7380b03cdacc359a7b15c6d7f2f1c9c SHA512: 4f21650b91fa75ff8cfd1719417dc6d61e8ac5835e5a4b16caac1ab72f21607e0b793dd6fdb16b3b4345df1e486017516b66754db592927382b3491e2fcc22f9 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16268 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-influxdb-v2_1.0.3_arm64.deb Size: 3487540 MD5sum: 6e4a5b56a8bde2da626eb1a122c19689 SHA1: 234c49e6bad61cb8c1350d9f8bb0f4d13956fac6 SHA256: bc359bb90faf339207dd5eb93c0cbc7bb8db5091e5786da598dab62663163fc7 SHA512: 82af33c505cc29dcfbc21c1996d811dae3e56b8d799fcf1eac64b3cb60ac0b1e8555a09acfe6807d06e846c5756d2875806170e774b09dc51187978f169b0e1a 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15595 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-influxdb-v2_1.0.3_armel.deb Size: 3473180 MD5sum: 02df2be8adcd86f27e64f8912a26a498 SHA1: 5aa65240d31d698c22f3b6a46e5f7a601c13ff9c SHA256: 1ffaa1c83f89152e8ee907dae7ad5e82d673fafcc3a9f0c88c19c918f08a851b SHA512: 641033d2fdd18375304929e75f1afbc808cddb44483ecd63155d47ad3b161b2c3b935e5d90b428b784d2d2deaec58ddb4adb3f43828897f55d6bacf7b086c8c4 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15489 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-influxdb-v2_1.0.3_armhf.deb Size: 3512680 MD5sum: b467dc162215b93d71952d36ed8e5725 SHA1: 8a253c6fa5fb507512474bf1b2129251b3a83903 SHA256: 9a1fd909a2dca0fa0fcc200ee75e82834746a53926e347cc9662349b1e6deaa6 SHA512: 8ca03784c04c3d8fb2cdc94dfce3eae30ee3cf497c2768681a6ebf75d3682126cc814685f5f2d66d763c8135a70ba68ecaf4c9c860e687585ebbcafa32c9e0b2 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19388 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-rocksdb_1.0.3_amd64.deb Size: 4328224 MD5sum: b692e41e11ba8198088462accb4423ba SHA1: 77694f5f58985db9ec8be98bfe9c01f2460d568b SHA256: 56c644a790df7eb97933694a2ac4286e6413a82621b7d8090cd17ec8b8d45124 SHA512: 47cfbe419ff0d45bc0619d59ef03aff10ef7e24fe4d39f0b6ea5f4a5ae86588ba96a8d2711ab58bcc80b0365d4360705db5bedf24e72754fb63870f2ab89e953 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17493 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-rocksdb_1.0.3_arm64.deb Size: 3887904 MD5sum: d1a4f57e631ff23e11adceeee71c5a77 SHA1: 81605d364ba647a8783dca34662782a7b499dd66 SHA256: 78523043efa6b14611271318da71197bdf0b57b0917f4e99884872fe93716885 SHA512: 3f7d8b57429a2282c87053a542111f4896a06f4aa06297a4814b0deaeb5d4b60023984e3b81b1d50dc1d699bb305497a76ec22d229bbf702e89617ef2096a69d 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15307 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-rocksdb_1.0.3_armel.deb Size: 3698516 MD5sum: 1ad1ec0df5b371bbe24f67cbd24f7262 SHA1: cc583cea1eb203737876bb4126d6f1b1c88838f8 SHA256: e82e5bfd4f9c6a80e3b8543b2b168e18186d35c34ae25ba5a4a2694b9ea45b25 SHA512: 847dcaa7271ffa31241a6e7ce1a9cd50170ccc16a7169abc754216443d7095c79df879bbd8cc05e854906387efb8cd8d5ef549e60076fc067c23be00fe53687a 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13400 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-rocksdb_1.0.3_armhf.deb Size: 3796748 MD5sum: 8405e7ac345c4dd703598a83de966136 SHA1: 3f078a41a89d894b26f4674696a786aa97f08a45 SHA256: 377a9c115c937bd3faa071226b866196efdd4bec7c6ef05e8bf40d39381e0b66 SHA512: 55db0a025b76a88141234b220bb7191009585502451034f7fdc1b470083412f02eaf9ea60b371e27fcfd3ee751013aea0a6b5650ffc87c09e761453bcd5512d7 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27267 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-s3_1.0.3_amd64.deb Size: 5514652 MD5sum: 410e9686235d5c470982e3dc12e8bc36 SHA1: 282425302760cb1873b12008479587f9594fd490 SHA256: 0c12ac3eb26455b6427b53cf2a5bf9cfebb27f6deb3e3f0bc71b2dd7a84b09b5 SHA512: 39a735d54184b254293413d2dcae30c53a7207dfdcec466d3ee521b2fc817c3bbcca6179010e45199ac202a2039a72c9844815fada7d0c4c8c3ece3e494fc59d 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26562 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-s3_1.0.3_arm64.deb Size: 5230564 MD5sum: a1c30909c81fd116f3b5e655e8a4478f SHA1: cc430bc1b1ea10965cb1ee682b09b043f66e924e SHA256: fcfd1e491b42f8dd602f8affdeb2074c2fd00f3ece7228b42351fa1552e2f10e SHA512: 3222af6e2b30682a535d32a921c793a9a8c291fa85dacd9e1f26057599581d062dfd3bd9b4dff5ee99f57b81d948ccdb0d908d71ca8f12caa2a72abed2ac4f0f 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25199 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-s3_1.0.3_armel.deb Size: 5104124 MD5sum: 2f623aeb5388456785f2238f954ec299 SHA1: 937196c4200190ff02c73525ac1ab0e832785804 SHA256: 4753456741c89c4c02520724ecee702245cdd187d05a4aa22b6b7c3e4838cd78 SHA512: d17561bb68c19457586384701377d2ac646d67a48c7eac0abb802506833054f8211603d139cef40e87d6cc8178dee560232fc2d445fa6b1126771e2ba14cd8c0 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24939 Depends: zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh-backend-s3_1.0.3_armhf.deb Size: 5138124 MD5sum: ef93c4ad1fa9341668a19d7f2940e44f SHA1: 4bafee0564e96deb0d77e55f42363534ea669568 SHA256: d0fb24bbe7153515c51b696d0e2b8bcdba7d8e99b833f7d7f9fc325437c559bb SHA512: 91421925a1723e7219169875e32e3244040062235f0d1fe1aa77a060424638b5000a223fd4a441e609acde88809c180ad367b9c752f94ce5206ce754cf15eea9 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20754 Depends: libc6 (>= 2.29) Filename: ./1.0.3/zenoh-bridge-dds_1.0.3_amd64.deb Size: 5306860 MD5sum: 1e658b7310f06e2efe0fe06766ce1895 SHA1: 77bcddfc004012818dc14ff6be37ff5897188bfb SHA256: 8847e52fac10ea95d52082d30888e265b268d46cf81d93bca6a1efdca63616a8 SHA512: d0855a2feee23f39d97dec5acea90bf075a45571504680a13fd2aa5a30624dd8f2039d48ef30fb865fe9a2babceb38d873b0e2d89497e96f257d990c4f8c7eeb 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18948 Depends: Filename: ./1.0.3/zenoh-bridge-dds_1.0.3_arm64.deb Size: 4794964 MD5sum: 04a432da2a2efd9f046ee26ddbfe0f8d SHA1: 23efd946000c34e996596173423b8e89e7c98927 SHA256: 0bf8d5750bc492ac30a6f4e6b9ae7e5070f5f1dfe2c9c93a50da7a6968ff8c4e SHA512: 98c7a6310e139c96184cd803d145f59b2fa5560975d504a821a34d70e6499ae2037d3555953440850ef0135bb4444646b9c11eec0e9ab892de154ba07cf1b077 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20115 Depends: Filename: ./1.0.3/zenoh-bridge-dds_1.0.3_armel.deb Size: 5068476 MD5sum: acabc56e8226883bff93e562ab11c9d2 SHA1: b3f69136d93d2d430d747e63d31527d4577dccf8 SHA256: 769d384fe13ccb551bb98c7e9c662d5449faacaba59d8a80cbe3267163f5f221 SHA512: 81fb24582ace7bb9237e7ce613fe73ed79068d2413ac68517be09375175e8ca3288ea4c9c317dde12a0d20a4f2b09e6eff99e3a1f695205caddab6bb73d5bb38 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19601 Depends: Filename: ./1.0.3/zenoh-bridge-dds_1.0.3_armhf.deb Size: 5120940 MD5sum: f77509b7eb1b274d280d57281e3829df SHA1: 6933c9022d26b2291830bdbd0b034a10d0cda324 SHA256: abb2e78bb6ac003f8b3e281f8af542e3b3202ade6bff2284ded42d7c3a0775bd SHA512: ce35c4b8bad17aeb18b14114beec0ef627db13ceac77b3f5962411f162e5bf7feb1be57a64ed43ad75a57822fc77928443834b3d8023001fe124d571d8154933 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20625 Depends: libc6 (>= 2.29) Filename: ./1.0.3/zenoh-bridge-mqtt_1.0.3_amd64.deb Size: 4975396 MD5sum: 26030bd30e936a8e31fb8a8fc768b42c SHA1: 3666fb21c80030c3cd8a2a10dcc811d80c49e477 SHA256: 901f132d1b5748a83b82872ea0c4ca363338a784f3e247d21b3c3a00a74dcc48 SHA512: 0ae33639e9e228f83dade6ff670f39343f7a2841ea4e33d512a1470d3f8bbd7a56ae89a35c59a7f6d72c984ed8629507460e81d421f4468afee277c5fbf48225 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18856 Depends: Filename: ./1.0.3/zenoh-bridge-mqtt_1.0.3_arm64.deb Size: 4504748 MD5sum: bb27b869fdf58fabed839ad0b9663965 SHA1: 35e38259675d3917d6b0b9e8d405618509b0c345 SHA256: 4eb7e1f237936a7fe25ccba19b27956b4b21376ee12b20202ecdea0a82cfa88a SHA512: 17e41832140a8eb2be93c67d39ae6a8c5ad5e971e21cb1435a67779abdec8cbd7594ebe41d9e896004e3f7e01bf276c7f02267dc766c5e5c496853ba866d4fcb 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20160 Depends: Filename: ./1.0.3/zenoh-bridge-mqtt_1.0.3_armel.deb Size: 4789440 MD5sum: e462d23b9c12d1b9acf066aba38baca7 SHA1: 1d867d518fb4c3a12e6b647618a821b643fe9fac SHA256: 5e9b1759cccce9998af12b00cf4158b8348bf768e47ceee4806cde1110a399c4 SHA512: 3da640513d089ed148c57a84ba92c5f5ccb494d234d4002ab57029862578a4f4c53c999e0e9504015040fe2970ee2dd2ce02f284e5e44367fe96a4ce1ce52738 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19882 Depends: Filename: ./1.0.3/zenoh-bridge-mqtt_1.0.3_armhf.deb Size: 4818868 MD5sum: 6304d99a91a4b1c47f531bc3cd448543 SHA1: 60a6e6c5c4131b32ebace8be17c56c8da4f2940f SHA256: c4b27328f78434380a0ff4bf9f95c01a3891c5071d112a75851d367db83751f8 SHA512: d04370e46ed3fe4ea9af14ad5d6ef6b4e8cb04f0e02b361daa5b777b98da8b5907fba56e3e06ceb3d9e9b7b44b49204140977ba45a87f26e39d1901afb2dcf33 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-ros2dds Architecture: amd64 Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21316 Depends: libc6 (>= 2.29) Filename: ./1.0.3/zenoh-bridge-ros2dds_1.0.3_amd64.deb Size: 5408188 MD5sum: 002e92f515ca815af30811fb53c3bceb SHA1: ecc157a0a8061ea837e79f581274a62573c1e798 SHA256: b7e1269a10eb36db9664cbfa11c235ef7f33dfc76b5e86e0b474c1b90dca3c0a SHA512: 2961a5196f9835bcb319a77ea403d14db601d8beb8a3f49f9d2e55b280b0245e04f1d389cdcf7b27308b5efb41df37aa39b85b9bf443596f69983dd17efc4f49 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19458 Depends: Filename: ./1.0.3/zenoh-bridge-ros2dds_1.0.3_arm64.deb Size: 4906588 MD5sum: f1f409a88eeb968a7c9c795febe90b81 SHA1: 98902248ed127dfc9096890146c70e7eede97370 SHA256: f24220103c926aafc85a57aa37dd0c55500f9d32bd4735132303a726244e2125 SHA512: 998e8eb334894839fa2a5a7efd26b11ada3cb54c1fdd130ca3946d65afcf941ce2883e470a1465cb98fbb864f7d56302912078d5f0741d3fc37c2f8c905b4f63 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20650 Depends: Filename: ./1.0.3/zenoh-bridge-ros2dds_1.0.3_armel.deb Size: 5175596 MD5sum: c225149cec3d2196bf76f2422421b98a SHA1: 04bfe7ec5a75e4e00d55e0947bba3e6d464963e4 SHA256: cd8482f1d069163e4eebdb3704b84aa2765f75abe3113e3973200b46891e0eaa SHA512: 6d6eeb024557af67b6f23591f8614b23a127a7063f4184650114252791b1d456a227fdc24fc1607cb213c9484667b4674f6859845114933f2d1ba85b80ee34ab 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20141 Depends: Filename: ./1.0.3/zenoh-bridge-ros2dds_1.0.3_armhf.deb Size: 5231972 MD5sum: 44e54e602faa33c06b7b0bdf9bc40ce8 SHA1: 8c703d9125fa16a446469338fdb0b5eb32b79853 SHA256: 1dbb870a317d20c2dc274be8720a3ad6c1ecca45a1663621531973e77ac2f681 SHA512: f945269cf90e78b720710ea18ab858d85b6709609297450553ec09b146d135549d6c583843a9d5afa2c01f56f457fd2232c42f0d8f388f0ae3d1f029d9c2e82c 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12832 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-dds_1.0.3_amd64.deb Size: 2577300 MD5sum: 3cd277f49bde73920a3413198645e01d SHA1: 240baf8de6c950043f5081b875cc45cbffbd45bc SHA256: a68cc10d8173b55ce259cd149e294ee0213a4395c554cc430f7d2bc561d9f2c2 SHA512: 46d5d0b55db22cb6f1c78ae682198a98c495295116d3453cbaed254780ca5de954804d6fa89f2cf51a6c9a0e6b984f78a054969894257aea1ca36178e0932b44 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11600 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-dds_1.0.3_arm64.deb Size: 2339116 MD5sum: 7de2c0453a9cc977fda451c597852ff3 SHA1: 5d42567c2be453d673fd4795c5ca3494450d158e SHA256: 2e464604d862fc7538babc7897a0a5c88a754b14ad31a1151295a45c346e2a77 SHA512: ea19bb143188bd9a4cc5fc697b4700dd9ff0a3d40bc968a7dc3ff3258f44edff74e1020447448dee9bb3e0edc45d85c94fcf90140dd33effd0c6f16d4e82362d 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9642 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-dds_1.0.3_armel.deb Size: 2188596 MD5sum: 823990eaa7d66b2c08a38b375a40f9c7 SHA1: fa471ed0c3c06ce2e77ec80ade0c065d12605ee3 SHA256: 45f95bbff28a70d50e08894ae1c4bf2d0f35211fdb2b17743b7e6bcfab6c7f27 SHA512: ed7c69b2bd27f64988fdd1a72b897962822a23be58359c9b2728058fbb64f5152850b542010ac2a97e2c5b5dc9f0c19c99881034c29ecbfcd896a92d046bd3b0 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9269 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-dds_1.0.3_armhf.deb Size: 2194800 MD5sum: 19c29a29e42d44420f70e08c27ba0510 SHA1: 97d80a729821018b9a537236a95559cf69dfa535 SHA256: d441931ca9653f19e4e7e989e6545646d223db33010aba4b3c762298ab336680 SHA512: 4b24ea3a8191c0c9122ee399c6a132abd2858cc7e248f33e69b91437ada50a43fac653965d5daf5fc95fd9705dd190a371807c7ed95315dc9a44f5140e048584 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14066 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-mqtt_1.0.3_amd64.deb Size: 2875844 MD5sum: 13e921b7499965cc1ea18407449f0b7e SHA1: 984b63642e534de96a460b0aa8c7e97b986e3078 SHA256: 2aaffe111da3048adfaf7b9c37b15ea52e9de899c75ceaabd5e722679f548db2 SHA512: 7180162b96c2c39120bdfb54b11b76ca7b2dea4d2b4dd21109594894dbeb7eba08cb06e673e3a52ba95093c74d0155bd3001b179220efb1c9799d5b4f7b43ef6 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12784 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-mqtt_1.0.3_arm64.deb Size: 2572648 MD5sum: 78ff690bdc75ed8b00035eecb7ab3ac6 SHA1: 8ebaaf30b4f0c3c8ae909c245969e5e69c51706d SHA256: 219d553e088ec3187847765f7ee22e0c1a63675b7c67de36d8c560c71f9777ea SHA512: 71413ef75594e9e253b6047b9d7d8f8692523a4343a59294c145562342ab616224a62a3117287677cae5f5f61797600a48951312ddcff5b8c000103046fd3c1a 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12775 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-mqtt_1.0.3_armel.deb Size: 2642944 MD5sum: a8412111af79287116f3596353a1b6cf SHA1: eb05929928eb89702fe8d8c11589cbb66fe0cf01 SHA256: 9ee3142c94d1772b1cd64dbbb221d1e8567ea2ef56e8dfbd7841b9a4f944d11a SHA512: 4b413867c10223aa621aff54137851c81e52741c7af6d6bfe8e96c181a85b56271a9b124721d6381aabce40e1e2dd1a9ce73607c13448cd4bf74842d09b18cb8 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12697 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-mqtt_1.0.3_armhf.deb Size: 2681644 MD5sum: c3aa85ffb95af7ee492e8e6c310c04e9 SHA1: 631e1b49c66de47d2c82a8472b4249d4a16c28dc SHA256: e5e88609c22344e3083d52b2a9f07e047bd3e48d694926f27daac8642df6c648 SHA512: c0aec2007c21eec9728b6e77388a14624a29fe626b3995ceb77c2e9880911eabf405cbe18eac755775626d612d25e7a3a42b9b13dd153207a4dd94a35046d774 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-remote-api Architecture: amd64 Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16055 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-remote-api_1.0.3_amd64.deb Size: 3410240 MD5sum: 1494e59bbdca4fcffa921ea646832de5 SHA1: 931888a103de83c8b3483353c86b53d2c67a5b0c SHA256: d0af32698ab1fb3c78171eeb7c120bcf8c0ab74825f3f4bc5cf61210089709bb SHA512: f6834a1f3a0c7cf1cdcb630070a5903f4d0ad396f4fd4748340ee75b6a7024ffafa00b706860ce4b7aa8e2bc83510ecc437dae845bcf239e2565f7a5dada25f1 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: arm64 Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15059 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-remote-api_1.0.3_arm64.deb Size: 3109132 MD5sum: b51fff3de6c0af6051dc4dcf9b2a030f SHA1: d5b4ae8377c7741a951e92d1fd9cad5df36ed8f3 SHA256: de23ce3843c6b5ed2db9f8a52c00d4d731f60171c6594cd9b8e48b2080f3c71f SHA512: 35bc1fa9ef47ed3c9735785e7ea1e23c73bcfdfd7e4d8f00de18d9f9dcee46895aa28bd629a50c3b8e85a98b9d46f42cbe335ffeaa372c58080273bb3655fe1e Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: armel Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14485 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-remote-api_1.0.3_armel.deb Size: 3075760 MD5sum: 7534b20c4a5b741f19ea5f452a03754f SHA1: eb33503f00885c7db843e795d5cced8459ccc639 SHA256: 093564f7747d4861bab079db5c9fd475ac16784d0db5d4582048654f8a451de5 SHA512: b66e9b53068d3e1a709573ffd7d4136ad9f8fffba03745d3a3ab7864fa140eabc8b74564c7d3a587a7058dcaa927c90d7f587aa796123c038813ed35b545e60c Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: armhf Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14362 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-remote-api_1.0.3_armhf.deb Size: 3112812 MD5sum: 344e8d39a3a033a74a19a8d1b56abc9a SHA1: 35afdb268f9db192c036a9eb04c2b45910349864 SHA256: 9796d8d61a8c6f95bf09df549f7c9c3f53f4bfd7afb5b8f83996d0b826befcdc SHA512: d7ef2055c476c4b35327ba24ee92b32b263e1293845c283e508f410d4aaaab46f1dd9482903843293bd66b1f86218adec01a40a3aef6106505563071d35b6988 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-rest Architecture: amd64 Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10858 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-rest_1.0.3_amd64.deb Size: 2087068 MD5sum: d33acc668ca8c56f56a768af2471ba50 SHA1: a4c0952c0dbe70ca469feb2563add45fa2612cd8 SHA256: 44fb55a8de77e452e184bcd3fa8b677d8a7575edf20ec1927c09a48b0144fdcb SHA512: c27347976701902a0fbb80bd34122b6610e9f9655ce45123fdda5d6b0558a0eca47c79113a5c81e87129a6b1ae28332ca9d7b680ed78a3ce36b6b39093de7073 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) . . Package: zenoh-plugin-rest Architecture: arm64 Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9844 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-rest_1.0.3_arm64.deb Size: 1911660 MD5sum: 8805e557e61c3b9ee45005f020c5532e SHA1: e9a98828c600d05362e861f1793d04ae8b59f046 SHA256: 4198d76e555f9bc087181ae378f967c23d23f795fb093a3a929b0259bcd1cabf SHA512: 87d2f702a16171f39ac1ff4a4b9c39fc31fdca6e2f136e46704e60238c49e9e4a013fb55bc9de33408edb44c945ff381f919298faba331a7f551ad0dea07bed7 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) . . Package: zenoh-plugin-rest Architecture: armel Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7978 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-rest_1.0.3_armel.deb Size: 1780296 MD5sum: 318436cc705d3aefd088272160c2c29c SHA1: cd3497a81322fbb844f38c7709eb4609865825fa SHA256: 78dbef3309b4cc38b47b246ec39b6d47d199cb3ae2a882bacc332d1369dc9f66 SHA512: fd1db730b360b1787b6d88b0dd837818fdc196bdb64b9f5f2164681079b2792dc6b5501e08aa9e9d5be73d85b19a1d94b172fbd4eabb0f96cf4539bc1cc094c3 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) . . Package: zenoh-plugin-rest Architecture: armhf Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7881 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-rest_1.0.3_armhf.deb Size: 1769116 MD5sum: 896d85a9fcd9f6154e135cdce9359a8a SHA1: ecdf0e0ed5758c5778f8a242739dd59595c25002 SHA256: fcc72bf28b7d29ad322e87efcb2c79a3f99c482f125dd410cb8aba8d4719553d SHA512: 8f29bf7f93816db037f795a56190f7b3197206f183f964b694a9c00a467b36de119c9c01ff1be9380abccc1a867080eb6aa967023ec693f313c0e0fd90d09ac1 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) . . Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13372 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-ros2dds_1.0.3_amd64.deb Size: 2672168 MD5sum: 85feb3da2386d354cc5c3449d4ce3305 SHA1: e86e4b64f4ea00c6b3c2e904a74077fced01ac3a SHA256: 8b2d4a50da8fc1d330d5459d00307a603559f1e05a207c90fa3b1cfd696ae6a8 SHA512: 95c81d544bebed606650eacc9d4f41141293942cdc543e59c4e6138798755795f3a0bf03928eaf99cb5f7ced17dec9e918f56ee36ae51f24a4301c72588363dd 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12100 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-ros2dds_1.0.3_arm64.deb Size: 2430428 MD5sum: 2228423b4213f27268fe951483b684da SHA1: 585c6f67c854de727a7f135ddfc61a6a31668edc SHA256: 2f7c3aff528cd232ef30b084b119dba97a9a8888e167c2ffbb642b7a3a98628d SHA512: e267464d97f3ca25beb3d6b06c967ea3bf1850eab40c55015c11bb2e6a58568a0a3af2530871534b536e6fe4ed9248f9169ce1fd943a212d5bfeccb99b1d3cfa 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10161 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-ros2dds_1.0.3_armel.deb Size: 2290188 MD5sum: ae1f8acdc63e4ef362b329a4900be9f0 SHA1: 01f4a74b6ed0c9a5504776f0687a901c057ac872 SHA256: 4303ef11ba7fdd6e065d9d0a52a8029a88807ffa03d9c60b6de86ee48834bd00 SHA512: 57ee069f889b4803eaf662fb04c7ade61b8b74a2346221a6b01aa1c6ab104c7874fe0e30f4a5f4f5eed06919ddba3ba64860af3d4467f6f0e66a567a37c22c98 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9784 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-ros2dds_1.0.3_armhf.deb Size: 2299676 MD5sum: 9a2e2049b249059561b98cb7013f0380 SHA1: 2f2fbf86c2a0d455fc7b4ad3ebb51fce9c08757b SHA256: 5be6525508742fe33befbaef04bbbede5f0dd581a0e9b869fff5f425ce331159 SHA512: 48e429d0476babd2e2dd40bd0f3fd33ce7582bc97d7f4bc59356ec5690ac8334ba71759abe5baf28163f7b8c4e782de60c2a792ec60787da4184c7a2b3c638ea 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 described 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/](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](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 maintaining 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 architecture 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10587 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-storage-manager_1.0.3_amd64.deb Size: 1980364 MD5sum: a76add53dd5cd09bce0f68def4025e6e SHA1: 75e1e20154219deb009ccb0894399e7fe4228cf8 SHA256: 8b921e3ee2cf1fedd26bc1c8465b6b5ee2a2eb243a1a63cb63f5edf0a461fc27 SHA512: c025796da513c122dd7f94b2f183d04318b2ad71d83e22a5a88959600c31bcfa3b1deb9668fb826d7453bd72170e96edb496d39522024d564cc1617eed6e6dcc 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) . . Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9552 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-storage-manager_1.0.3_arm64.deb Size: 1807636 MD5sum: 3e81238682840f4c7063bb92834dbd92 SHA1: 071989b859b8549fae7fb97f95cfb8d78a94faad SHA256: 9ce53cc3b55ff01234111aa2c66571ee29c3f7c8585821a957754d994202f97f SHA512: a0607384296b56fb6e6fae8a60f0ade49884cfafd87181058af30592f747a3a6f7360f2bfb58a0c9ff3e42319629b5f3eeb27a9b6a21a01e0ecb00df76f97c66 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) . . Package: zenoh-plugin-storage-manager Architecture: armel Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7736 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-storage-manager_1.0.3_armel.deb Size: 1699452 MD5sum: e484f9f32658ecb1f58b155d3fc167c7 SHA1: 278298f990da2f6f391669ab62ef64662038b1da SHA256: d40256ed70cc4431f5da0d0b22b21b75f83a26bc1c0df3dc7e658a8fc27dc2da SHA512: b13a6692c29b0df00bb43d2df9b50353db5e2c32e60d96c454a3e76b845e520227f6d52b436211ffb96524eeb00473624f86ad2714662d4abd733ce029c94199 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) . . Package: zenoh-plugin-storage-manager Architecture: armhf Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7627 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-storage-manager_1.0.3_armhf.deb Size: 1684828 MD5sum: a61aad055bca1e78ed6a4517f56a2bb7 SHA1: b8e4683db2bbd2b7f58d70d69b37385180e98cc0 SHA256: 11e7fa8a2d205f0c0d0034df4ba2fa086c928de7396a68f35f0f36a706eb22d0 SHA512: a28eb4239dc4274afc132379372713cc473b6440e8e43fec36de72d9c29a0062b7cdebe364d300e055a7e6d9ca0b4c907860a890a517a3ef161883c422066669 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) . . Package: zenoh-plugin-webserver Architecture: amd64 Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13295 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-webserver_1.0.3_amd64.deb Size: 2521028 MD5sum: 71456e73915e3dd967692c07455e5d7e SHA1: f840c09aae133cad2d7cac7d203f9031f66810f5 SHA256: 51d8b4dd09cebeed8ef6b8a2fc93be740f44ec1930c7be846da4212a377a4239 SHA512: ec37f72a95d9f1e0b80d3c4ea7874a792b5304a5c110e59953e59282f6c1dd80a4037074f68897123ee4376f9081b4e40a29deb68ec66176bec9f83b0af03cc0 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12456 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-webserver_1.0.3_arm64.deb Size: 2345736 MD5sum: 2e6de67e1d18bbc6bd5708f4119889db SHA1: 9955ed7ea55669080598f58fa9ee47679b03bf5c SHA256: 47d8498850a0896eb8dd83175f0a4022eb7530b88569ff5a5c7f5466ea41121b SHA512: 487fa3a09413b9f9b3904bdf423e14e4cae3c8797ca98a82234f53cae81f9eb6cb10d575f53bc19273f14342d8c845e3506e7194535ce8592ce646038b2cb634 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10202 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-webserver_1.0.3_armel.deb Size: 2144704 MD5sum: e3c109502c310c22ffa50137346b238f SHA1: ec519d6b88b8ba3bf688be2399dc6654d8198292 SHA256: 3953a654de2f6281f6fa5330b3c7e6b0a86ea0e97799de11f9ed5cad779c2ab1 SHA512: c1ee902a5eb23a0cb52b5b05fcda33a8c8aeabb39540ec2da6fc36093ee1ead25653ddad41f003353ab1db3c7f05a7f4f4598651a89dac040aa1cf26dc42b321 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10072 Depends: zenohd (=1.0.3) Filename: ./1.0.3/zenoh-plugin-webserver_1.0.3_armhf.deb Size: 2132436 MD5sum: 4a0c78d09c942e57d018e8d701e61bcf SHA1: 863ad65c0de331b6a658c8e8ee2fb0122fbb564d SHA256: 260d4e95d2770e5fedbac8a99d57c804f477c122fb05eba50b730c08e90b0274 SHA512: f4fa04124dd44c4038f621b9c2d391fb0bd844dfe0ba71ef81953436e134f8badc4af6b3400a7ce7f2f30696da8fc93b4437890a1862f8a38ab2f845aa5ba5f1 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: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-storage-manager (=1.0.3), zenohd (=1.0.3), zenoh-plugin-rest (=1.0.3) Filename: ./1.0.3/zenoh_1.0.3_amd64.deb Size: 17416 MD5sum: 127bb4dca1244a5d0b082c4679361586 SHA1: 3c961cd8189f6e82f80e25395f75fa9cc54221ab SHA256: 32545500d3d8d4597b264e4b1d3b87ff241c74bc8a97fe353c41658558d355e1 SHA512: cdf3c91a87b107800e436d372b8506b0dd7353a10d48884cc8ced1c11a71a8073e0972384dc1d4ca6ef8eb5d95dd03ec8c123bf1f10a5bae959de1e0210022e2 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenoh Architecture: arm64 Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.3), zenoh-plugin-storage-manager (=1.0.3), zenoh-plugin-rest (=1.0.3) Filename: ./1.0.3/zenoh_1.0.3_arm64.deb Size: 17416 MD5sum: 5e3800b6a7e71633202a9c71380f9538 SHA1: aebec58893ff728ec1e2f5ac16bff0c7db3a620e SHA256: d67233c413613c25ad3e2ae959d612ac7bc371009b52f1f9a8c6ac730243c269 SHA512: 71e8e9364e3fa7daa7603364907b53be7e96afe213620ee68832b517e45a6847a279adc3f8a47c648f725bb1e1508451eb7c4273334e199e92d8130b24777c81 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenoh Architecture: armel Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.3), zenoh-plugin-rest (=1.0.3), zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh_1.0.3_armel.deb Size: 17416 MD5sum: 33b488a37c0766aa4adeaefac4850143 SHA1: 87e5d469a1732c1e1a7516f84248b8f7f3fe3e2a SHA256: 3564f783e22d8f74d4d2f8c386d0847b19d69c4ad493683cbf234cf0022ed104 SHA512: 5c975227e3208a90aa4d2fe38e48af7292e4e8aaf42d3a9609a1f0307b1ab8ab84e97971749f7974f055a91924094a202b4201c2982f19b8c14a90ecb1c09aa6 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenoh Architecture: armhf Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenohd (=1.0.3), zenoh-plugin-rest (=1.0.3), zenoh-plugin-storage-manager (=1.0.3) Filename: ./1.0.3/zenoh_1.0.3_armhf.deb Size: 17416 MD5sum: 3fc1b807d9ecb3e0e6b353beb9f53813 SHA1: 62e649a37c0f5e79698e62291e9dc1b1c12b8109 SHA256: d71f5af3ea6f61f421df773c70c7b677712cba1c5836b2173954cf95cc87a77e SHA512: 982f6d23dc31eb7b8a04118351e8cf81079333de19cfdc547d99bb69619d9c0119b672063f05ff3dda35a79578b6d822370dc137f09e577d52f53fcd365aa482 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenohd Architecture: amd64 Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18146 Depends: libc6 (>= 2.29) Filename: ./1.0.3/zenohd_1.0.3_amd64.deb Size: 4446292 MD5sum: 9dad6fcc6404a980a21071992fb605a5 SHA1: 0875d8da52afeb73cf2a5996b75f50b8ef73b827 SHA256: bc97a9f2eb1ed2eba329e20613cd5d1321320a041602363eac4c81973532ad94 SHA512: 60f36166869300095a473439fc233ac2fb6cf1c836512791c25b7060643960e6698eb5555fbb7cbff6c537ed77d64b6fe96e7c8baf6544364ec1f8f3b4c4492f Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenohd Architecture: arm64 Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16306 Depends: Filename: ./1.0.3/zenohd_1.0.3_arm64.deb Size: 4004688 MD5sum: f781d73f4975fc6938c7df0a1892f1d5 SHA1: 30bf6d418dc78a3a9d8ebfad69147e748cba8474 SHA256: 311aa451c53921158ba1960a0cb726269c944718910962cc5ad57334328fc84f SHA512: 0b38a9d519abfe619d50e371190b1199087db4935501b98757a9c19c2a53ca1d2ef89ec0a4ef1dcf2369cb769f916827720525b7ffd62bc16e028ec2bc11403a Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenohd Architecture: armel Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17652 Depends: Filename: ./1.0.3/zenohd_1.0.3_armel.deb Size: 4351464 MD5sum: 1bc6147fc20e2b923111cdf045f5d3a3 SHA1: 35ed6cf276d1650dc540fc6b1a84346526cc326b SHA256: 8d0355a2e6a8e6b3e1da3ec0b34fcbf75420bb365aab0a70e2fda98dab577e9a SHA512: 4af3da2740f493bb8de253b24fa4bc173a99c562a1b40555fe04b9f3a9e7c3bfdb0b8a8389bf9c90fbf3672a32a6ab1ccf54db010bbce520454f9e8e0edecb4b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenohd Architecture: armhf Version: 1.0.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17429 Depends: Filename: ./1.0.3/zenohd_1.0.3_armhf.deb Size: 4411236 MD5sum: ff2ecca8caa8591bea61d98fd56b31b2 SHA1: 218c46354ec7c5b73a6f51989db92a5dba5eb81c SHA256: 08811f33b281bc085e670064c66fab33a023f42c2915b1f2d17a76528262a2dc SHA512: a34e4ca89293da7d0cda0b337356abbd84f03a6b7eb6fabf14ba79cef801539c027c77d13d0b5ae045f1c1179cb8c91dd97aefc4fc4439e76f09c17ec499a684 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: libzenohc-armv7-dev Architecture: armhf Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30349 Depends: libzenohc-armv7 (=1.0.4) Filename: ./1.0.4/libzenohc-armv7-dev_1.0.4_armhf.deb Size: 9308692 MD5sum: a7d6fd6d0002f4a8deca5fc14adcd900 SHA1: f10fe1f1a770eb7ec9a262faec0a112d3dbdd25b SHA256: 207991af58d8894b86bf2fed501e04bec2dd8576aa2cab8f5523df8948a427b2 SHA512: 6513ac0694fd2cbe8cbab317a9648d4bd68ed2945284a54a38ce9f7f5d03fad830ef170d734c39bc1bf998d9021b71e8ef23ec377bbe91041bb5070ba7f3b9ab Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17983 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohc-armv7_1.0.4_armhf.deb Size: 6849304 MD5sum: 64771939de75bec5652efed3734da67f SHA1: 5ce6b48ec86b8e75921e6ab401d35ea395f1f1ab SHA256: 764d05664795c84e3ee72046c3a7dceaf44eea50ffae54db3029a9ab2ace82ab SHA512: 80f2bd70b9bc76b1d4ad3ddba93bd9e3892457f0c3240acb772252d8de2d2ffe9991356cb363a46a94eba2f9c9c00569080200447f0d7963f2c82cf13b24b9d1 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 38410 Depends: libzenohc (=1.0.4) Filename: ./1.0.4/libzenohc-dev_1.0.4_amd64.deb Size: 8912514 MD5sum: 76d263cf6e150a54e1350ba1d3562f5d SHA1: 6276430cbae37d1e985a62cfd5d42e42c9e627b1 SHA256: 2e6c8638fe7ca003f8fd69ff1aa9b10db9b7764f2f9f4be16e2f9dcc2d70d177 SHA512: 357dce267d7166db11265646a4897048d609beac59cd079b0f369091f49cb178de430ee12cb48d264e7605dc65ff79cb7b2aa076855225a36f3b474bba2be916 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 38729 Depends: libzenohc (=1.0.4) Filename: ./1.0.4/libzenohc-dev_1.0.4_arm64.deb Size: 9002890 MD5sum: 4f73b56c521c35892237858232d1e07d SHA1: fdbb23dc9ca987020582b494dbe909dc6c726c27 SHA256: 5f3e5e363f797d7930824f5c27fecfccd964643c296ab3bee0c8d5aed6870df5 SHA512: 9adbb4b71a2c53cd9d62bbf9efbfebb8a37b71aafea67b6c0205620537a88c57f445be90280def163cb0f9382eee8412a486a25e4c2a53a662375cd6eaa8e347 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31194 Depends: libzenohc (=1.0.4) Filename: ./1.0.4/libzenohc-dev_1.0.4_armel.deb Size: 9493264 MD5sum: 6b22fc48b2849e3418143b90a8fbc19e SHA1: e45fc3769bcd48e1bb2e26f43b95198a761301c0 SHA256: 7785eaa74c8eb706e5b7863ebd8fb9ab56232066b623893d05df2736d98515a1 SHA512: 7ee874bbd1782b03111e3f48e4f524a44dc92404bf51d9a085b8c1d44d8c1cd449118800dc9b2eeee8ab8a054bb1d86184cd897bf65eb0dcb19f0d23531894f8 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31360 Depends: libzenohc (=1.0.4) Filename: ./1.0.4/libzenohc-dev_1.0.4_armhf.deb Size: 9594918 MD5sum: b28daa481046b0b3f773f80c22c54309 SHA1: f49c0cde5a214f270009542fbc5c60a9b4a5623a SHA256: ebd2602de53d33a1ab5e99a2e1bf9b2586ec9650c1704c027086bee5836df14c SHA512: 60a2703bc1235d8455086b1973f4c0e2c40215d2da86ab8e132fdf1645b20c58a10a1439db0c137662ecf2afc7f4338a08a978f92e780e23ed76c74d6b931535 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 34283 Depends: libzenohc-musl (=1.0.4) Filename: ./1.0.4/libzenohc-musl-dev_1.0.4_amd64.deb Size: 8673116 MD5sum: 6e2d46840da14cfaf537b9e47b30e2fd SHA1: 95b860f97238704342082f620b393ac68c6476e5 SHA256: c087e59a610b8abc393544b8a2df0f6af86cf6772ff6b8dbddb7e55f34c2881a SHA512: e8871f038bd9871915eec9fe665c9ae7d6c8aed508ec9d497d2678411829b8774a9b75599bfb87277f7890cdff2156ad7b839f5c7b8f46754c319e61fffe6abb Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 36743 Depends: libzenohc-musl (=1.0.4) Filename: ./1.0.4/libzenohc-musl-dev_1.0.4_arm64.deb Size: 8746816 MD5sum: d2bcdd5b36aa3113e8e998b9014e11de SHA1: ee312ef5fcac6f4a5a67ac7861544741318ea450 SHA256: ce299c434ba53792a53340762ac7a2150d60ff2db80e92ae59a251b74633f628 SHA512: 77f2acc9b341939bbaf8ba6520c9cad6dc904366f6739390b8cc601beda78b7f842ff5f66c0f04f1e7ec37e37aff75c766a5f92315b6d7c1a152089a0e4a14d7 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18121 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohc-musl_1.0.4_amd64.deb Size: 6569552 MD5sum: 8933371987be9d46e187ff22181bb89b SHA1: 821f3bf23f4014ebfa81952640b5618a6a9c8a56 SHA256: f3aefa40edb27f52ce33163c3f97efa676e67b3fe0eec80c488fa557ee7e6ba9 SHA512: 3344bf05745c868e18a1d78e13034497f3798f8bcb01c8a0155ab39994125990870ff674704b6d6ac6e036995f3b9343a6d74f92476e355e68589acf3811c397 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 16822 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohc-musl_1.0.4_arm64.deb Size: 6257532 MD5sum: 08ae21bfb22375eac2ae0e98076db02d SHA1: 50f3cb3c1836cea6928f195a2cfed1cdec93292a SHA256: ecfc8a90f5aa1f55b3fba57891965f6c9ebf6f92db5755c843aa81cbb47f8d86 SHA512: 55a89da7f51f66ce12dc946ec486eecfbee70729e1b214637d18d51f330ae4de584f25caf03bcf3a9f0b7552e3d57438f134f50473ae598cc815c42f9cb7b049 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18703 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohc_1.0.4_amd64.deb Size: 6584298 MD5sum: b0d8e4b88e14c7607a6e94a9680c88a2 SHA1: 27c413bf1d9a1b42d8ffc9a91f8a092894254c06 SHA256: 7e21069ed613833dcc83c9f4d38c8eae481f3dc8450598edcce4493f808b3e7d SHA512: 736e979e2dbbf2f96e78375d7666b276267bf94653d0d7eea1128abf22ba0b452687b1c5e65c79fcae41dec31440f6e6343386a97ae3c7a67589f100a4399c7b Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17168 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohc_1.0.4_arm64.deb Size: 6313682 MD5sum: 02793f93cc8c292dd345a016bca6d9e4 SHA1: 7ab808dd0dfbdf78bb97b5663e6836ced3aae981 SHA256: 5ae54a82a111aae81365e820b4aff8523d1e044c392bf01755237022c8cd8432 SHA512: 2a72f0693cb2bc6f84eee2f8b85b62f74452b55271ec894a6fe09be346d03d3f829a8e6024ce10a7963071a5221f57e27f2460f429924a95edfcfe68d12d6f52 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18387 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohc_1.0.4_armel.deb Size: 6934524 MD5sum: 27c2beca29a82df73ea2347afc98ba1c SHA1: 6668e31af722ba63ee8a4d44e3ae242aa6b93c19 SHA256: 5204c822ab97c7c4d4e5c99c816808b070ba0ccf150d0017f2d8ab26370359cf SHA512: fc68c6e843d44328e289fd8b552f4ae4b2849b6a8291618c42d030a3d692777af52711e3433f2917e5d909ef62443908f81f30621be0b708c2c833a487366b25 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18376 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohc_1.0.4_armhf.deb Size: 7005110 MD5sum: 147f96246adb7b65a494cda3fbaab7c8 SHA1: 4607a4d9722698357a3f015099f5d7154f5d020d SHA256: f3d2ba41e16222a769cb69f7602c6ed17edd6da255c1f9a5471e4efb717bfeed SHA512: afdcd7cd26930e9a418c33fa132312bff5e74c06f4a78a25cb99381684a8fe74ad4134d1cef5305bbdccded51c448417d2a9e1417923b6f5ad63e7fbd0d48f3e Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 379 Filename: ./1.0.4/libzenohcpp-dev_1.0.4_all.deb Size: 48402 MD5sum: d6296194503713b9c67ee8ee1d8cc4bb SHA1: 6cb0c7cdd2a15a710338c45a85d2e8e467724e7b SHA256: d39a94752a7d0df5e73a568cc61a87c44e84cf49a17ca887f5943aee2c3947c4 SHA512: eb7eae088b904ea0db0e627ce7df54f53ca8253f3d057974cb807afdae7cc22da6f171efdaa6ca4ed3d1751eef26462bc82f20773e5fbc9bfb42f886e81c1c73 Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1116 Depends: libzenohpico-armv6 (=1.0.4) Filename: ./1.0.4/libzenohpico-armv6-dev_1.0.4_arm.deb Size: 221934 MD5sum: 6cbcbd994e7541a1819b22a94b53e396 SHA1: f0ab712c0d8b96f8abf404f750c0c0107f697363 SHA256: 0d66aca435a30508392cf6b75d50b030b63f0647e92c3c83a2cc7a41fc123bfc SHA512: 00449c326d67063342b76d29f94406eb8c9d780b4f2ba9d664ea335db55dbc2ffb3d5d95c69201f6671eb2aa654eea23b7e9b735c897779aa0bc09139a6736e0 Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 328 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohpico-armv6_1.0.4_arm.deb Size: 133288 MD5sum: 9195c8f09f29bec292f69a01d6c9397b SHA1: ffbeb1d0fa4276390d921577b8c1539597387336 SHA256: a21c8d701569436cce14aa6ba1e3b44b1c0cbc9e970599715d505e0d5c44fa09 SHA512: 5cd6612118e6ad484d498d1fc56ef90dc20da16d9b26eb26d691c54ed9fdb200fc31d1606b16d798e850f34641e87190ba7660aadb254d1c81c553b5293fd6fc Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1111 Depends: libzenohpico-armv7a (=1.0.4) Filename: ./1.0.4/libzenohpico-armv7a-dev_1.0.4_armhf.deb Size: 221148 MD5sum: f04d942c0410fd0e7ed4fec13d67bed0 SHA1: 45791dea08343eec7a87988a0230c78243db3eb6 SHA256: 4b8ed7946bd3d7a2e748e28dd161f23b158c5f038056dba9943e04929903baf6 SHA512: 186a1dc2bf28babe743c510c53539d3905c31ccced06ee0de4a4adab84420854383dc0a938791fcd9ef78e9d6808e78de4f05978a3c3aa2a6fe5bacfc8dedeca Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 328 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohpico-armv7a_1.0.4_armhf.deb Size: 133260 MD5sum: 8577bb584749f8ef2572ccf1e9e31b57 SHA1: 9b72355edf020da4c6c8eaf60494194035c4f554 SHA256: 8a7ee08c5f216f0f9777e4bd859238ed6504e8ef5d98da8ff632046a1cfa8d1f SHA512: 315c0bd7cb8389945717e3a68806b512b9e8983042f026d37a8a9baf9349281279c25f4afcce806f0d2f42b16e14f3dcb1e35e243d4c60b6013ac0f17464c960 Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1358 Depends: libzenohpico (=1.0.4) Filename: ./1.0.4/libzenohpico-dev_1.0.4_amd64.deb Size: 268958 MD5sum: 007989c9f2895ca6ac1aae98c7313d56 SHA1: 9e2d107d21b835807986f632acd348b8ee90ce31 SHA256: 80f938e5c36cb0c4a143c4204290fd1288b9986a1655e3cc69fe143b78a731bf SHA512: 2a3dbc931f4cb03e5b6d82b42d38257e35080028c8f04536fd7d07e28f2dcfad87b03b8863e2348c52823c718df30ed30143346343322c094584be637405e0e5 Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1115 Depends: libzenohpico (=1.0.4) Filename: ./1.0.4/libzenohpico-dev_1.0.4_arm.deb Size: 221324 MD5sum: 715a1626b418e8cdaacc3cf2c4cae1c3 SHA1: 680f59346899aba04cf3dedbdfb310b13640c242 SHA256: 8f355becbbf4801daad9a456ec916f21076ec162ad812a6479b5a46a0d187e34 SHA512: e442c4dc0f2865dfabcd8c11eb47fc75aa393e5d845346e3d76a60709a7e3bcc8de18b89bef4cefef943d551c4cf49c5c8bffa962c158e8438eb2ec27f84b69f Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1369 Depends: libzenohpico (=1.0.4) Filename: ./1.0.4/libzenohpico-dev_1.0.4_arm64.deb Size: 265522 MD5sum: 4c08113c9f3647bf4be854cdc5607e53 SHA1: 9f97fefd4cdf1c8b283dcc7782d10f7238f162be SHA256: 86031d52449690816c7904d624d0feaf57ace439428684b4696dad1c3cbff5ff SHA512: 9c448a45eab3dddeca63126c9bae59cb40209d2667915babc684651c71dfc37af5f0b3d746ecfc9416fd6b2ba8b5efcdb790993dfb18ac02b6f82dba4afacff8 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1112 Depends: libzenohpico (=1.0.4) Filename: ./1.0.4/libzenohpico-dev_1.0.4_armhf.deb Size: 221056 MD5sum: 01a98b759fed704f1879fb50826f8d1a SHA1: 7b3e55fa40d07e503fbc36d2b665b38ba545937c SHA256: 58f91828e4e86853a12fea92d14f597ea51d23d8b25639925e4601487fef3068 SHA512: 3b145e205150bc76c77b0a6977bf8088ca4b669dcaae3f12a0fda8b732527eddeb55626b168380076c0ec267369908cdd9c80d9215481b9a54e9f226e3cc3e09 Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1325 Depends: libzenohpico (=1.0.4) Filename: ./1.0.4/libzenohpico-dev_1.0.4_i386.deb Size: 290248 MD5sum: c3aac7fad68b15841ff2d7df37f3d9d8 SHA1: 702a61c65af5e222aa54fb8a267a9cdb8e9998a3 SHA256: 4dd8253112da032a8ce0dbcf990b6ddf584bf4a6f04db9ae0a4d884460e59e3d SHA512: 06dfbfa5adcae9e55ef26ba01107750bae4f3d2e9afa663c49cdc68a69cd95c0949c8bf235c4bfd42b283b5144781637399f7538c416984abfaa58c3fb76bb5e Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1260 Depends: libzenohpico (=1.0.4) Filename: ./1.0.4/libzenohpico-dev_1.0.4_mips.deb Size: 253376 MD5sum: b0008af1b3a464372b2a9758c285989b SHA1: f56d19f1fd30d3065f20707bdd306b84079bffed SHA256: 392e8d05457e21d3ada83c5d96eddf571b3e72077f055a8ed888b3a1f34589ca SHA512: 13244186eee6720a2942e1ef0ed70485e4dd1bbd3dacfabd5384020715f5f0722b6ad27170d53e1d58feafb1e9924d05c594c6ad761ccc54fd77e6fb0a4cc37f Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 455 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohpico_1.0.4_amd64.deb Size: 165942 MD5sum: 2d3554110859cdd5020af51434aab329 SHA1: b2f4ed4c6e62648da6a151444a7020c0afe69038 SHA256: e64524ef89e5b76dd2110b0c204042781fbc79528e80bc9a295d571fe38b32b3 SHA512: 99ee5cc89644a348f75166a994dc0471a4b93d36d3419a6fcea6b584d8807c26841455682b0ec20b79a45804d4c327a362170538768a27ed61c22b133faf0492 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 355 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohpico_1.0.4_arm.deb Size: 141478 MD5sum: 8cad33ff7c229f361937eef010f8cfdc SHA1: 93561ccb2f1cadb00c5bff46a148d100619978a4 SHA256: 3e5c45dfdbd2093a968216e58428e4ce3090a70c1faf24c8bc6b11005ac4a696 SHA512: e43eded151f1008910d17a8f395182b5bd88b2985dd94313e1fe8ace07dc44067fdb3d987602379935e4fcbb1fbec091983a60127da34bc4538db0793fd2066a Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 469 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohpico_1.0.4_arm64.deb Size: 163920 MD5sum: 190075778493bbe07682528caa8c2569 SHA1: 366aeeeba2defd9bd26ccade6f0418226b5a29c6 SHA256: 054ffb3d958f412fcbb27cba33b5b62c6e6c86a94343b8dc21c0da9e2cf9e78a SHA512: 98a68f3b8adaef1904c8f841f3af2c58b62857b9b4eb89a844ae08c60657753e96240580aa940384d63932db0c04bdf6476c5b66d6698260632c17742e1c4d7a Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 330 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohpico_1.0.4_armhf.deb Size: 134542 MD5sum: 2f4914e255ed98c2b9272afa050887ff SHA1: f94de208b3c148427d901044d8b106ebaf90984c SHA256: 1ec1c0253e35bf79945e65bb8fa27cd5b92fcf5a91f7631ee514a152935583a3 SHA512: 48bb948b0e40220b0319a851eff49c590a6c09e419dae67bb9e50d3e10623d76b56472937ee334b3d212fb3ac4e31d3a7dab63d372ec1e0004f1068d3c77c060 Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 478 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohpico_1.0.4_i386.deb Size: 188000 MD5sum: eea2d0ea83b403ba4e094eeb1bae0227 SHA1: b5cdacd5a697c292e5e9895e1dd870b1b7a5eff8 SHA256: 7db90759d0b0d65d41c970c29da2836a1bc5590f9dbe93ec93cdf5f2ef2152e0 SHA512: f5b7047bcb6ef4cb9350e04666b4b6a0d49b8e28ca54325472bc1b894a5a4e836198b73606c6c07eb68a09815b2813f4a9377992719f1ad50a7974779ef3997d Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.0.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 434 Depends: libc6 (>=2.12) Filename: ./1.0.4/libzenohpico_1.0.4_mips.deb Size: 147980 MD5sum: 181371b3284a030e657751d8311a9d98 SHA1: 6bc256d2b180fb851d5cac4ec247cdf4ac42a191 SHA256: 2da16af667e1b68bb5465ba0659c72b84ea1c603113acb524eee179cffe559de SHA512: 4b3074504931610bfde0e05846071e50c526df18851dd9d2975dbf3519f4663054c9ef80b89ab04f962501e2ec4ecb1080ac80835bdf81ce585e40e28b70a2ca Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20839 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-filesystem_1.0.4_amd64.deb Size: 4599980 MD5sum: 881634eb2ba29ca3df38678ef40e3986 SHA1: 19310a57fa7ce84c10dc6d189c074890f056776b SHA256: 1634545141896d43b7b37942935b66e98f295ba05678efc45ca6c234c5c31696 SHA512: d96df0e2de58b2885cd2777f0b291ad72cf0cb0e366760d8720d3a2cade47b0f5be893e0738906dd2f6ed663253073eaa43c3897edf6f25fe7b8b120aa10a107 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18940 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-filesystem_1.0.4_arm64.deb Size: 4139056 MD5sum: 4d639056df9c8acb17b59d801909fb14 SHA1: 3f9b0172e6ec6776638628c524ffc3534fa103ca SHA256: a901d786c02809f706527721fc0294d87b43fc7c66e4a2727875669bcf9aa2fd SHA512: 67b6858af88ac022f78104ac344994c412b22a587e2fcccb732f211afbddbb8c0f63de502f8ee546d5605a495eb90193908d798de8075eb4c55ae7990c9c8b2d 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16514 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-filesystem_1.0.4_armel.deb Size: 3910876 MD5sum: bd7b1bc0868f090838b94788921e3293 SHA1: 8fb2a46578f7507dc412cc3780102d29a7e7caf5 SHA256: 251e47df6b8974d3a6f43716d73d41ae05f5f536b4a24294b4c55e61a6794b28 SHA512: e512ea5887f86d06cb3ed8d63a623cae4112d49f332a14fb46d1670f7eb7f3f227b97ded5e6feeeb46cef1edbd89fa88bc838ef0d0c6689a09aac1eaef3a2b80 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14629 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-filesystem_1.0.4_armhf.deb Size: 4010660 MD5sum: 599d605018c1c0665a1b87bd7bab1873 SHA1: 93894bb5fe75b4e0572740e0813c231f76736091 SHA256: 39cdf00edc9c6a072ee3ae573c93223b6c86e872232b51860f2696cceb21accd SHA512: 052e388b0847d8c6267c40db45c52c695a05b829a9f065efb53af90ecef6e3187152301d4132429843af5a7cab8f589b26922b636fc0fd771f486880778c546b 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](https://zenoh.io/docs/manual/abstractions/#storage) 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15713 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-influxdb-v1_1.0.4_amd64.deb Size: 3129544 MD5sum: 63ddeb7c70ce6a3bbcf4cafc28eab0c0 SHA1: 1cc76ad795fdf2a4b7836ca83de77861485644fc SHA256: a7e42045001fb308cfd4209660828fc48ee238c1fcf51b4f104940b0838e3832 SHA512: 15201788f96b50dca3462b6be23fcf5b82d4a6b96c497c8b508c8d9839080eae8965bed758bbce616f1dadbde580fbd080686c9788073d474ee6e132609964bb 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14029 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-influxdb-v1_1.0.4_arm64.deb Size: 2810952 MD5sum: 9b04f5dd78471b6a6d9e44fdbfc4086b SHA1: f5552d7827c95e222b437aed4383dc87e87c45f4 SHA256: 634209beb977616aeab344b9ee78995a6c433cb732281d6d5dff8a3d9c700115 SHA512: a56d57c1c61acfa523b4b650e55e62f2f56448782cafa3e3f46cfc7affc849458fa20257ef21947c607da994ebbf448433f15d7e3eb786839c7e109a0d087df6 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11806 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-influxdb-v1_1.0.4_armel.deb Size: 2551588 MD5sum: defc5b89985fe7cf2cace3136a9ead74 SHA1: 820a4072ba0a7c2387db2b81e909cea6113fd7a3 SHA256: 2ba64b5640a3c59160ec87464a9147865fe1693aa5f0b550d7b3cfd5aa158009 SHA512: 0d33247f1edf972c515d396ea240079282339e471b6237a0e6b0ba398ed720adb982b2c4ef805b2705c9d8bdbf027c821680d0f069bad32d7d1294864195aa11 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11682 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-influxdb-v1_1.0.4_armhf.deb Size: 2544268 MD5sum: 991086cbec1e582a3ae07d918373f902 SHA1: cc93827af71e6265fc1ca47137fcd08d7abd6fbb SHA256: a229460950baf87ae90522e2e2fdf0d4b8b9383fc0f8adc481e757cb55295203 SHA512: a30d4451d6ed6a32bbc40aad02ab6318c18c03893891f6a6c7eb7b16f5ba4267d30c0ce2749b06a3389e9eea6662f965e3a9f17eae68c50d7b4d744625253346 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17302 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-influxdb-v2_1.0.4_amd64.deb Size: 3802276 MD5sum: d3dc5419f46033115878a1e790f8ae54 SHA1: 591cdb31b79a604fad3d74188c7b7b3cb7a4864f SHA256: 334f842c63dbddd612de92c95864ac5b9795fa658fa9214f6c5322e31bdcda18 SHA512: 0a12b2b037f0fb96094b3daf426cb7ac8eee7bc6bd2d46cac3576a0e3136749f28e38d7efbd98d7bb53efd036054ee83583fd890f11f55f7687de116b9d211b0 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16256 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-influxdb-v2_1.0.4_arm64.deb Size: 3489748 MD5sum: 192cab2d7b6b826d62f66e2beda9cff7 SHA1: 232a43f998903b985323eb52e5502927c68dfcc1 SHA256: c1aa740aec4b2488e6fbcd0d0cd210868fe1a8c80e87119849091c80576996aa SHA512: 3b6699e725160b8dac61bd18329e2f74b34d6a533e23197533fe54b114a272310c37cb65e791ef5b04a8a8933a7dede08c92e7e01b3b5bd8ff513a19b8effa78 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15595 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-influxdb-v2_1.0.4_armel.deb Size: 3469304 MD5sum: c1664c354bfefed9ad37c0de2c64b0f4 SHA1: 80e14d7add73dd54ec924ce902783d18c766bee9 SHA256: 84c6ad1594ce4f8d2c9f205b873df227221e65b054af5240d5e3a675cf284c76 SHA512: d7230c03e73d35bd5a09dc81b30734905a8486ede60bddf6ffb6a7399b765d32e3d1c2dc82958d84b8f14ecc263333644d4430dbda407379a458bfb50afdb368 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15490 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-influxdb-v2_1.0.4_armhf.deb Size: 3512560 MD5sum: 4f291ebb2fcdeec1f6ea048d6ea32596 SHA1: 08b6fe86d11fac4b3ce5298919491ca2e5ae348d SHA256: 7c93402b4c1b421682a8bd4ce32876d24e1b2f07b4cecee2296565d2921917af SHA512: c5a033e87b785d6a3b11c379325c427c658bf702ab492c8b4fbd84fc64ece6cb7fdb6ea5237de06ba04afb7e99e5812e0a3cefada4bfd0177eb0c061a376363d 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19387 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-rocksdb_1.0.4_amd64.deb Size: 4328892 MD5sum: a669a205340e3ce6700a188067775f24 SHA1: d47a06064bfdac28e43c30265932585fa309ffe1 SHA256: 1a5d41b3e26af256bba7940e4666e0bcfccec9698bab9166808a43b3e2f977fe SHA512: bec9623591844d31665800e7118fdc4350016f59d9a914b00cd527985e150f4e965e128f7542f18de766059aefd924acfe4f35982f2bf7ca10d7cfc28d1bc4c0 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17494 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-rocksdb_1.0.4_arm64.deb Size: 3884828 MD5sum: 38fed9ef2b8f8febdb48a92127c9fdf0 SHA1: 193bf988e8c262eb4875a8ad66396a8e03709e6d SHA256: c6a4264c05d9a335c687140410ac5c26b7638bc0f7f16a43fddba14959e7a456 SHA512: b4206d00df1476bf2babc8984fdc86928d9f74d41b2d0160f4da66d635e6a65f80fd4aa3366b79c2d4f86762832994c14761440e8f989fedde6a942d77546514 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15307 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-rocksdb_1.0.4_armel.deb Size: 3699944 MD5sum: 2ae67abdfcf8122054c7be1fe0ad0e27 SHA1: 9abfe0ef82cd3d9ea5fbdda16886c86980b5cb80 SHA256: 24af696a17947a7bc67255d253d857bd8aff9506cd7ea53bfea8521c16a400b1 SHA512: 37be579d308b4d43ae918a32c3d0a6d3eab2ca5042f1a83f97b2e09645e743d600b739c2730bec6c0ac96f54ec950c9ffbec05760605af3bf3e4f4a71fd92d5e 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13400 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-rocksdb_1.0.4_armhf.deb Size: 3799660 MD5sum: a4563b66cf065621698e52a789c5dcf8 SHA1: 4e3f0c12abea0e64341bc67141a59d85a234ea17 SHA256: 15fcbb02036fd79b72b8758c6d09d2800987199553f3fdd0dca1b5721d266d4c SHA512: ea773717d6f10eef1791b7206c16221076424cf63acfb294ee93f8b0195cf34e94990516f89dc09995ea87f91171ec2fbab240317095a180158b930cfc6e6db6 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27267 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-s3_1.0.4_amd64.deb Size: 5516412 MD5sum: 670b4309a4598a5cbb61a4ffaa38308f SHA1: a195c69218209eb6c0dca48015d4adfffcd93ce8 SHA256: 1aa9b0c2440ee224d3bdba3eab087ba8e49da650868ccd2da8737cb7ed10b9c5 SHA512: 9b3c30c9e1c0d8eed2a57a08ccfa0a287ff208b397fbc921bdb354b9d3a662e0e0e031c9acdae92bb2fb4126e3096f2e49e60cd3f0c59516f052e1f28e333115 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26483 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-s3_1.0.4_arm64.deb Size: 5228048 MD5sum: c0f01c8e35e4b98c56c1ca51f8a91298 SHA1: 773158a30d3846042bbb6a430776c5415c50137b SHA256: ee910f00855ed40d0ee38b7c0f839155225a9e0e6a21be12b6bbede2fe2d53e2 SHA512: 7553b77d83c9e4dce7b493efcb903ccb1f41e8225eb9e31683866ea963c74be8d858532f17488aef3d1e0bfa21184fd313d03b8c35c05a87a5403a8370c16907 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25169 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-s3_1.0.4_armel.deb Size: 5092824 MD5sum: 0b6332ed9604cf7ce6d2b2b50d6aa5a2 SHA1: 8dec7ace461b870ace7e256acdf48d5242411fb7 SHA256: 63cd6333e4e16ef0d83b36630934061242484507ad207bd89f0249dd17b79cc4 SHA512: f32fe12c89bc3811a092060ad8729f26050674e7bfb4377c6be89a761e5a24137c5e130b925d4fbab74ec9e7de320fc6daa9f27a1bb1465c1d0e1eeed89c6cc4 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24957 Depends: zenoh-plugin-storage-manager (=1.0.4) Filename: ./1.0.4/zenoh-backend-s3_1.0.4_armhf.deb Size: 5142264 MD5sum: 46ebd003c3d003b706757590cfad9c5b SHA1: 68426a68f70b2daa6e0ca916a7e9e84fc8674cd3 SHA256: ca966c0231587520e065f20d27205dfd5e2147ba53ae0d4519c7819c6999f774 SHA512: 6c1d4c115325cfdf1b3f0aee19ed1f78b039cfac897c925e1b69474acd6d1d56c3f000c209c55d36580ca10aef72fd586ae7e6f556fd33ce7d40684fa5c518a1 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: "", secret_key: "", }, }, }, }, }, // 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20924 Depends: libc6 (>= 2.29) Filename: ./1.0.4/zenoh-bridge-dds_1.0.4_amd64.deb Size: 5344008 MD5sum: bcd4fade03b82b9345db25b61486bb59 SHA1: 6903f296b6c89daadd5e047fc62e4acde9c8557c SHA256: b1cadba15cd7d8276c00c68fd3ddfaa061c0bf12b2d9cec85d5e5a15fc5ecb1b SHA512: 2bb4b800820b4efdb4b0da1950b3b20294ef42e8386cb0d05eab41d88831e91ea8ccc9eb38e15ee7a4bedc3a9fabac7d7856a0f7270a72aa5621c9de4fbbc9ba 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19096 Depends: Filename: ./1.0.4/zenoh-bridge-dds_1.0.4_arm64.deb Size: 4828140 MD5sum: 45df662049ea9b03c4113c27b251e76d SHA1: 55aa8358cc22ee2b0f33b7adbe9173881d843d3a SHA256: a5151cb7f33d8e2be7e2e2793ae373e87aea20be99eced8b2e158f2f97ccb047 SHA512: 8d89e4804dce6eb57652b136d06baef4680da898d7262d48dbd833f414ac4139f9fe333c9ee494eca994ce283868b5cbba44f35c5f7a3c9239b8ce58278cade7 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20301 Depends: Filename: ./1.0.4/zenoh-bridge-dds_1.0.4_armel.deb Size: 5110240 MD5sum: fd8cf7980e7ab27d1a60fd0176531a21 SHA1: 4a5162adcd831954aa0943392fd7ededb3da8631 SHA256: 9d7bbf067e7af6fe33d2a5fb4e24924b6c1d5a110a6fedf7300f49c51865abba SHA512: fee1c29e69ba84aed25980038a09dd18af6aa426400c047df3672d0dcffab6f36c26d746df9a81582c468a71179dba180751d75565dae37a39fe870e85f2279e 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19782 Depends: Filename: ./1.0.4/zenoh-bridge-dds_1.0.4_armhf.deb Size: 5157676 MD5sum: 7025769b2448768b51a9d9c7d334c8a6 SHA1: b9c6514813a06d13cad868024a7d1c67af309ebc SHA256: 0bb140e4a79b321c2c3b9c287bbe822a63ab7d8631bfa9ee3f9c9c65dfa52eeb SHA512: 454e9ad30630ba5bbb725911e0f99a31c7035869b1892174da001d4cd6f53e6c3f3f68df746d5076a5b8648d34644a35bb53ef45c611a55d91e0b1b97b6b0a8b 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21211 Depends: libc6 (>= 2.29) Filename: ./1.0.4/zenoh-bridge-mqtt_1.0.4_amd64.deb Size: 5028440 MD5sum: 1d71d0fe0aaf8d959e59d699b5e074e5 SHA1: 45032e78c73153acec0f556506fce12472f74f66 SHA256: 31d795dd76e6d81e7810be2f1f6bc44e7ce445ce86ffcca0283f1f449c7a42f3 SHA512: 08ae812b4e13117279cc1cb598789d5a9c3b1a93f01207eacfc6d5f6eba9b0dc7e6713051957eefaf2918564d49642f3408322006d70043348d7779f02728977 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19438 Depends: Filename: ./1.0.4/zenoh-bridge-mqtt_1.0.4_arm64.deb Size: 4548336 MD5sum: 7911c5f9cff68f84eaedfb70426a5c35 SHA1: c83791ed5daae483a27f5cd716ed11b056a015b1 SHA256: ffe2baf33801cfd876d8d59b7db9c29b0a48479cfebc402ed0da9a4ce8ecf886 SHA512: 1003e7630e7874929a8357de7823c2fb630b4f49203b213a9f3cfa14dcfde37ed2c25032ad2d99de6fc84362a8833892645f39f1ff62f901012afd508a1eea87 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20625 Depends: Filename: ./1.0.4/zenoh-bridge-mqtt_1.0.4_armel.deb Size: 4838312 MD5sum: 999cb7e829ef8da7ac8f557aaaacac4e SHA1: 9c3f2d29cee1a7af88e52964dec385c464364e25 SHA256: 8488afab35e5072ad5b1d41c51c8b7af8ac4fc402fe77e2dc6316e8bc4161885 SHA512: 0757d2fa967027cdf13f4e3b65e5d33fb52c57a8a65bd48ac166b7b7e03065c0400b3378a822fc553b1fbe3811c0569ed09aea9db7dd0bb9116e2808ab00dcb0 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20346 Depends: Filename: ./1.0.4/zenoh-bridge-mqtt_1.0.4_armhf.deb Size: 4868760 MD5sum: a827317f21e20797475cd9e13b49c19e SHA1: b299a3a5478473da3fedf2a0b5958bd6e5ecaa5d SHA256: 0c67b8a82160e8ac467701139c9d63a47fa5bd24be664c4b9413ce97a8c9f88d SHA512: f9fbac5608153b6fef9b08510525a607679c65c1899ca8c27cb047ba150739984d74f1b2fd1dfc5700639c50dbe19b2ff435dffe491610c34158a6161dbe06c6 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-ros2dds Architecture: amd64 Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21512 Depends: libc6 (>= 2.29) Filename: ./1.0.4/zenoh-bridge-ros2dds_1.0.4_amd64.deb Size: 5451980 MD5sum: abe62c418dabc5202aa046c18d8cda37 SHA1: a57c0e66a8b1ae33c095bbc3477a985cb5d527b0 SHA256: 88d7271cb098665022214740de9cd0a04458d46706962a09764198a49743de65 SHA512: bb8b3d309045df4a651ede1e2b18fef822f5b5c090e7ef52edeaac3c1b65903370d1e25134b64725f4a012afacd090e1f34ba00f1c9cd3a0f0eab44c5ffde1de 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19655 Depends: Filename: ./1.0.4/zenoh-bridge-ros2dds_1.0.4_arm64.deb Size: 4938936 MD5sum: 75401611767edaaa32b8e5ac567aa7fa SHA1: daf85f5ebc4b27d9c6aa71d86eaf6c965b3d33e0 SHA256: 679411d618d1cc1ef128b8b9884054d5a92dad31ac753ba03f917429799d9067 SHA512: e6c0a30529b83e67954dbb8fd742281ffacb01d78785cb5867a0b47de4e2dce37077bbe6032da9bc33611db5c39905494b04436d3e1871c8d9b0fae71825b2a8 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20858 Depends: Filename: ./1.0.4/zenoh-bridge-ros2dds_1.0.4_armel.deb Size: 5223940 MD5sum: cef9d1c89336bf6c6efba2e2aeb7fe74 SHA1: 8c0d887fc4b09562503fd6a7f7d76bd8d4df8c7c SHA256: 6b2d149ec779c0ea07b998f88435cf488e7d361d218e46103510757f0b9aa268 SHA512: 57fafd3b691413bf405fb5d019208814184e6a117a0eda5cfd9dcf798568bceda4e61a50a326a9ce076cc8c48c399273288c44b02363a9712ce3d81058138276 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20342 Depends: Filename: ./1.0.4/zenoh-bridge-ros2dds_1.0.4_armhf.deb Size: 5277032 MD5sum: c1a9abf4c4c99403d5e6eb43d317f99c SHA1: 57228898d4f771ee46d5d0833667534980a12102 SHA256: 26d2626e87ab1fa989713325494483d8ae4667b8a138862020e15bb6fbab0ba5 SHA512: 17734eb42a139943cd7a2970e0251a25f1a968b18c7849d8840a0ea02e61f164f2a0c6e89ca002b321a0c9672a8dff277d39b4fcb50061eda85e20114e133784 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12859 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-dds_1.0.4_amd64.deb Size: 2590536 MD5sum: 51ddb0d2968de9f0e30d4bf842a96ff1 SHA1: 4708f3a3fc573141962596bc3c1395c2b75532ae SHA256: ca38d65b28a415033c015eabb6a6015781132c2b3b69f09aad8347ad96748e2b SHA512: 9c750855f3be9088c5dcdd7a4beb91a488dfc369e5e8b9a2c15d22de6d422d22bde55111562f3f9eb16e617a35b81c6fb158d7e68450d3580ae8cb28b8dfc71a 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11616 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-dds_1.0.4_arm64.deb Size: 2347736 MD5sum: 5d8c127e2d1d0e47442bd1cdfb022d2b SHA1: 6384e5e932ddf75325119ea0dd937e3542d4df69 SHA256: 5e1cd41c1fcc911621b9f7f710f3139c5faf685244a00d2cd3e8f9969c9859f4 SHA512: 7cbdd465611a6d3392ef79a36a055d92834864041edc1fbc1fc3657789b2785c0c7ab35232ebea65e574678bc05ecb98a68250d2a9f9681b353ea5442a62f215 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9682 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-dds_1.0.4_armel.deb Size: 2199432 MD5sum: 950c406e2595362decdfa2a5a318f044 SHA1: f238c6f9002166b9e81302a216bdaac8d354e852 SHA256: 2148eda334f5489ea9d15bfc82b0b5a37ef841c446d29f63ebbdc3d3365a28a6 SHA512: e3440d6b4b3a9ecbf3ef75aad9cf0a82269d4fc375b15be6aa8b5d09b13629ffae3443a6a4b849e7fc0c1b709962c760370e66e57a3913b0cfb2abb351ed46f3 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9303 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-dds_1.0.4_armhf.deb Size: 2206208 MD5sum: 4f221dc92a3277e625da356330626957 SHA1: 76e42027627b1fb52b4f4e7969729de807bd935c SHA256: b75941d6e18667861494395adfaf959f8804d1e24fe522d3359ea076b929af89 SHA512: d03974411c13bf5626a2ade6a5572e61a5b51a0c50262d1f976e4bdc8cdb00b567d6242043a32489bad0a07fc53a3018da1a8351e98d40f5a63440e0e447e909 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14116 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-mqtt_1.0.4_amd64.deb Size: 2893484 MD5sum: 19b63f6ceab7d4e302a110221dc6e3f1 SHA1: d6ab930cc73d0f01ecae6de49c04034d8e347c72 SHA256: 9f1f5ee0836009827fa2284fdd6a69a2affa2d07e99d6b1d3b970e1a2a5dee77 SHA512: f0836180a8e3d139dd87b78d9eadd0fc48d1163ca32030a9d6569a31d481ee69f0f8338d6137882d45f05587b6c65e8eb0a24ef5c7e490a3de29c14cf2a26e28 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12837 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-mqtt_1.0.4_arm64.deb Size: 2587048 MD5sum: 53a2a7dcb8130ac3260a7bab09fd0bf8 SHA1: 5e08ba5806469d5e473e845448491864f093dd57 SHA256: cdf4704ec5a2cb018cf74adfc64c529f239997c6bee982063710d604c0583307 SHA512: 2e8333c80381d74e8ea84fb5d2512ba3807a3f43440515a419fbf77610750895526c650b241328073eaaabe1cfb19262a76992aaf8fe00ae68a660a660768dc4 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12832 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-mqtt_1.0.4_armel.deb Size: 2652848 MD5sum: 8e8c00e43c54aa65e72d41e8c4f1a231 SHA1: cf83bf62ad2c6ea8147b687276da736cfb406d74 SHA256: 1f719615080f941b8bab6446a155c89a77c5b1fd63170a742ee2d9d1beaf2f99 SHA512: 920e0c3542d9a342c0d3ef9cf8dd266c55787147f07ae2f8c8651757ea345666ef4a0bc2d17b5647c3a9d0ac94dfbd962f66c75960a95f936eb6707b4492c803 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12749 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-mqtt_1.0.4_armhf.deb Size: 2695408 MD5sum: d70a739f7320addad6c14441f09357d9 SHA1: df04604c2110665c02e553d32212a336b77f6898 SHA256: 35231cd4875a8d875d8de7c120e3d8cf33036bbf8763d16ae5d02889a442c377 SHA512: fdc9821b086f8966d95c05e45be5fe9a662d82742414214a20a1f8e3cf88d2b65fbf7c2bc184e85f8fad01b98771546f0e300196304d4c1ae5f8d55558ac0254 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-remote-api Architecture: amd64 Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16028 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-remote-api_1.0.4_amd64.deb Size: 3415792 MD5sum: 4d926380b761119204d5cae5e1b90adf SHA1: 3e798d991eaa1f2926d16f37dcdf1726c6437bb3 SHA256: c2a1b7358d7ecb4494b65c5f2dbbf3f3b74995d2d79c8f92e7926ee343211ff5 SHA512: 24ff2a07d39acf78bacd03359fc1e99a02ea73c7c326becdb4b20fc25548ceed150f5410c8b2a0379d86c6042ecdfecc0c6f24220492cad42f7ecc135797148e Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: arm64 Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15044 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-remote-api_1.0.4_arm64.deb Size: 3111436 MD5sum: c33d6fe55b4b4cb9d766ad47972a8d8a SHA1: 94c3e1baafbb8ec296838be1586e9a3f2148fecc SHA256: 8cdfe4adda989d6e58015ba5179dd92e1b664000d3215cd2dd323c2abe950afe SHA512: eb79b3715cfe649e05478b565fa11e5be927e9edac95afcd4a8a787f861f90fc8569af1c665163d610ab548504c3d73359ba91ed72de193b03b0f05b3b74df7c Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: armel Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14500 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-remote-api_1.0.4_armel.deb Size: 3077700 MD5sum: f5d4873ef437b894c5c2c20d83d0f314 SHA1: c7e9d957e4a669340088ed2ff00976a6c2c24672 SHA256: f10b9cd69fbbc5ef2d3ed838ad7ab8db46ddf6f54617fa626ffe32fe63d0823f SHA512: b48efa6063863e3189cbe03f76a9e3b74b20f82e282e764d2a26c479d3b56a660301a0cbc95e813be615bb45ee7e5d1f87f4aba0ed22607b2e74c70d6713387c Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: armhf Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14380 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-remote-api_1.0.4_armhf.deb Size: 3112864 MD5sum: f040b48f2c671b8f0f58fa1958282fed SHA1: 98c81cff774f2da628460c8860b3e5e5e76a9026 SHA256: 7a6605efa295bee6fe0dc8ab6368a6e6ec06e2a8d25b5f49374daea22d4f7207 SHA512: 39dd4e7afaf65389d87512a181222b52293c4f6de650d8fb42983a5617f35291841020f0927d116a27bf0da606d1085f418a6a5a9c9ff9e4d7e8f04d33050212 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-rest Architecture: amd64 Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10885 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-rest_1.0.4_amd64.deb Size: 2096604 MD5sum: 89ccc40f32efabfaf619c3e56a8e37ae SHA1: 9bf2e261765cc949e15e0b395c201feb64418914 SHA256: aa4aa0779000b85a051326f8a6d4be70176607e10cce34f69bd1a12aa82b11d2 SHA512: 6d70fe09e4ee7ab02f61e3523cd4b060c69a901935bfcd4cafbacfb2cf0a4795b229280895bdc3330cf06d768dc0e625a8b2cbf1d2d93f8aaa907f5fee12090e 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) . . Package: zenoh-plugin-rest Architecture: arm64 Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9869 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-rest_1.0.4_arm64.deb Size: 1919456 MD5sum: f0b35ab58e423241b5d24e3bb8058a91 SHA1: 6a7005a07430fb810d75206bb5ce01bb68516372 SHA256: a83940e0c3dcff5793964714c6730a636577e4a6dd3db53020ccc4b5fd3e0fc6 SHA512: 670b89434a282e9ee9cdc29caed2e699583c4f95aa1fabdf5fe7b4b082fb793e1e1702f53cd3d8a80039f5b680d73b90f309ecf92bb1879be61e05a87505f72b 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) . . Package: zenoh-plugin-rest Architecture: armel Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8018 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-rest_1.0.4_armel.deb Size: 1793144 MD5sum: f63c27a2359e1862b37f1549bc734dc3 SHA1: fd13277beba2233cf68254cd308a8f8c1d01f708 SHA256: 493756e4aec5bce5691e9780f67a21a13d1f423b4ef876d81e00fc1d94e9711a SHA512: 815a1546f2dbe103565c9c1f1c32fb4ad71adc093b1381e14e6e169fece556104fd9b78da7caee5ea35a2596bc0f0df3ce5e7c6ed849812ebb31df2b993bcf07 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) . . Package: zenoh-plugin-rest Architecture: armhf Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7921 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-rest_1.0.4_armhf.deb Size: 1781444 MD5sum: 94cbb53b932fb9723364ac539f2e3530 SHA1: 39712ce3e9edc840b856062de1f1e7e476f8c206 SHA256: 01f5551ccedfcac1f52605643df692d471e70e3a2eaa724c99cda77a6040e55b SHA512: 3436db085143d363644ee37504df74aafbe45d50120f9f66c477d62929db61c68ee40ab2ea284adca892f00613801cd4e6b03a90a8b0d8316e1db00e1c956df7 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) . . Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13427 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-ros2dds_1.0.4_amd64.deb Size: 2684332 MD5sum: 3e682da9fd2c6ef16cbb1808989984ed SHA1: 161025a39f0e7ae80141d30c72fca25d8dc5c6c1 SHA256: 146a124a043d4b9e15411f607b81e5be91b90d70baec1a071f4b51b427a64a24 SHA512: 35d6d6db91244c471fdbf549907c8511453da6562ab0d989cd92bf05f8d6d42db7e3a11fb198ea1c223fb4002abc526fd29fca62ecee9284c3f35817f9ef46f2 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 described 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/](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](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 maintaining 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12156 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-ros2dds_1.0.4_arm64.deb Size: 2445628 MD5sum: 31b5f4049e879e9f2c82aba28e73dc36 SHA1: 475b943ce044635431b0dd56b2941797ac3cadd8 SHA256: c3f59c933e9ad5efdcbff17a5a22488413613caaaaf8e0d7da62a26b2d822e80 SHA512: 4a6a9d003a5607577352f6f9b55e0b1b103f108829ab0e26b019c7fa0a26ba1b1fa1edff2ae04f99e45d8eedb26384c77224f52bb9e24d31aa7b1b17feeb7740 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 described 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/](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](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 maintaining 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10220 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-ros2dds_1.0.4_armel.deb Size: 2306912 MD5sum: dfb24b31157a6fd7682e2c42e303f657 SHA1: adf618ef8e4cc823c00f0e2ab5381cd2bbe12464 SHA256: 3f7631979ac69907b5613eba37fe3ab6a38e9f0f21133909ff2448867e457c52 SHA512: 7f5f39c7c5e0bd9bc6b0520aa00f7d5e6ab334884f91bfbde357010b074f27485774f952a30af4534c701e11bbf9d2a7758362ec376bf6eb8b54a4fdc4af440a 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 described 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/](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](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 maintaining 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9842 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-ros2dds_1.0.4_armhf.deb Size: 2316332 MD5sum: d8a03d98049f41cdda78d7d516db17e9 SHA1: 73d621f3042d38d8fe600094cc5514134280b95d SHA256: 1926ea23ae30b9be8a4f203b69dca0336612ed141945a1559f06aa2061f4d79f SHA512: 2764c6733890c43282e27a7fd063a8da8efcafcdbdfca88f8e2a62a5c2d7f2f514ea77b5222dd3eddad95dc8c9adbdb7f483d983616531dc6208146faec540be 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 described 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/](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](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 maintaining 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10617 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-storage-manager_1.0.4_amd64.deb Size: 1986416 MD5sum: 7b2c262630443d6bc9ae3e3ddd3f7ab6 SHA1: b31e6cc4d083a5014e1ccd1e98e5443098c51782 SHA256: 19291103ac09a456380cb14f5e724170a3c7a4aa2502f1a8c0541212570e2e79 SHA512: 1ef11b680d939007117782e09bc232f234c715d0d7d68e8309060f815dfbf770ca5bfe87a3a01a54e643dbb170e8816c74eb5c353cdc5d1ae16fbcee44fa4bd5 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) . . Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9585 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-storage-manager_1.0.4_arm64.deb Size: 1815072 MD5sum: 359e2cb28f0470e34200e0a3dbaa866b SHA1: a6f3aba526a0a96dd083ae93faba063afc0ca5bb SHA256: 924c6bcadcaf22eb0c1fca86e7b8c776ec4152c570d8a1af269b5dea210b5122 SHA512: 67d9a2d9b7522b9feb981843ec105d79ae66d746f0b2372c41d69a5dccd6f7b1f3419136f30ec7ec40eb630cc8f5abd34731d83b45547df99f8367dcf966dab1 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) . . Package: zenoh-plugin-storage-manager Architecture: armel Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7776 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-storage-manager_1.0.4_armel.deb Size: 1707348 MD5sum: 00ba335a4d2562b441107cc974f28ca6 SHA1: 0d4e57b44e4f719f3db935a1680864e20e4d18de SHA256: e25641981dac4c4b7bca6edc3d9274059b903fa863ee1ded91a1008034d64dbc SHA512: 696b23399f869ad54bb6011c13d749b34bc094cec1107b3bee794f3752c50bfd3fb7507aa9e6fa9dfb616987375827a3dcc510ee85e5d88564b34cd266327edb 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) . . Package: zenoh-plugin-storage-manager Architecture: armhf Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7662 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-storage-manager_1.0.4_armhf.deb Size: 1693008 MD5sum: 8cc2d1f1c11a008d1c820a68c254e974 SHA1: b0645c55313a58c58637db76ba5e4c5e9817ba0c SHA256: b36f48cbed1b3c3bb038983e268277fa8775f375d879502c48babb539cb7a2f2 SHA512: c8717aacacba499d9813a6cdfcc0b997a9b93eb6428a7a332a0e933de00cefe0fccfdc386af5b6bab63569711455db420938d7591c3d661b3aab16a90c6b7175 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) . . Package: zenoh-plugin-webserver Architecture: amd64 Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13329 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-webserver_1.0.4_amd64.deb Size: 2530924 MD5sum: 070ae36e2597d433be14e7c1e221d270 SHA1: 7d71b0cef17f72f45c3bb78fde3a1ff5d2bec6cb SHA256: 9be6bb60a1211ce2b2412273a625ee68d7849a8645f573d4e6fe78fecd118867 SHA512: ea2f7de3a767f0d8c82f723d9aaaeeb13bf4b816d1ee6b4045aeaeba6887805a13c249f41d2ba4965622e190417c2307f49bdd09c99107bfad331979ff86952c 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12518 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-webserver_1.0.4_arm64.deb Size: 2354416 MD5sum: 7bf672cee74cd155b8a51d33943a0b37 SHA1: 09e71ba668192cb9c44c5c6b45dd4eca3250a7d1 SHA256: fb5b156f121ecd1a4ae5baf51b9c608ac7d00149eee21632d1c9c6839a146097 SHA512: d1a711795a1e844c2cff1e22d736975a43f46b0562be056e374527d1ba4ca2f6d2212a1f752f05f17fb13fa00ad0ffdd3f0c3a77fc4fada00bf95f0cd081bffc 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10231 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-webserver_1.0.4_armel.deb Size: 2156532 MD5sum: e015fefcfddc588b8ad9cd0d80d8d3b7 SHA1: 2e67218782110f6941de65038f8ae870889bce51 SHA256: 12d28701c24c06403d261144757dae0230a1848f42d652ad4518fce8412da96c SHA512: e4604c523f6fd689ec336712d3209b1a7fb96bdc0e80b58e3188f10f2d5852ade2e6acb76d7b3403341ef7e72f45f431e2b083ace74edc4e1ccc395e3aebfb70 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10096 Depends: zenohd (=1.0.4) Filename: ./1.0.4/zenoh-plugin-webserver_1.0.4_armhf.deb Size: 2140088 MD5sum: 1ca5e5b158ee9c76ca64269dafa71f1b SHA1: dccddd4e47ea234d1e3f4b415cdab2727ea0c343 SHA256: 5575c82ef9838d4c9cb77c560b57b6495bfe61d37908538a6001e95a13e12a1b SHA512: a10c17c26e2d6af6b04f88c04cacdd8d55c99b32c68a195f83bf7265ddce6dc5dceddd796b54fd9ab61bfd6abaf5d313d1bfa319725ec6488cb33cdd074ab18b 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: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.4), zenoh-plugin-storage-manager (=1.0.4), zenohd (=1.0.4) Filename: ./1.0.4/zenoh_1.0.4_amd64.deb Size: 17420 MD5sum: ea7af3081244de9b499f3efe9d650484 SHA1: e1f071fa0e6996b14bb23ddd9b2851664de75bdb SHA256: 915ac3f98cce6075b621645750f0f7fa85c36f3a3bb26869296230e00bb12bdb SHA512: c60dc6b532be15a94c4d204d8bff2d0f6a63765d7cae93a419b5cc3e1f51c35670063c80f7815587e28b7c354b4ed0fc568be7a1e1384c506a38062bc5fdc53d Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenoh Architecture: arm64 Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.4), zenoh-plugin-storage-manager (=1.0.4), zenohd (=1.0.4) Filename: ./1.0.4/zenoh_1.0.4_arm64.deb Size: 17420 MD5sum: 393b84f26ce84c2244cefcce7dbf16c9 SHA1: 012f0b632d4d1a7b4f47569b2ee73060ab33cf85 SHA256: 49ee534d4a37c3118c87b36c83bfb3d90db62ff0aee14ed72646555edfc0d7be SHA512: d98a05b6d803cf0902987b3e830fc758518ca57f0abfa49ce5b212c79d2f857e6022cc5258cbba6619ae1723728f9d883237000849282281b7e2de38fe3e4b8e Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenoh Architecture: armel Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.4), zenoh-plugin-storage-manager (=1.0.4), zenohd (=1.0.4) Filename: ./1.0.4/zenoh_1.0.4_armel.deb Size: 17424 MD5sum: 70039eb69b06692170172358f0b4592d SHA1: d226738038bf38b2f25cdbe295ede2a9848bec67 SHA256: 15e2a631f9e47a45e97632f1e6d4a10745b97527ae724011ae8dbaa014003351 SHA512: a8794a255de2c3571af8dda5de81709ef7e2a400658f0605e48cb6a87b8d332bfb418be6f291501001dad90a8ded33e21e9e6a1dcea41ea3bd9ec6a811d70612 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenoh Architecture: armhf Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.0.4), zenoh-plugin-storage-manager (=1.0.4), zenohd (=1.0.4) Filename: ./1.0.4/zenoh_1.0.4_armhf.deb Size: 17424 MD5sum: 6fe52a07625ab9288329bf83626f6a8d SHA1: a641730b68430b6ab160bf1d5aa0c8e7787243e7 SHA256: a5595d9e59dae62f2df4f58380546878a7e788037eb5e836239a6d6e1a118533 SHA512: 1bd24866f7d35c4ff2f3df07bd96a1446c89d886452de127ae77462856125b47e510c64a37af2c9445748fa1259c32483271400be6a0ed77286b7086730b02ca Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenohd Architecture: amd64 Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18375 Depends: Filename: ./1.0.4/zenohd_1.0.4_amd64.deb Size: 4491368 MD5sum: 7b6d90814c336d14c88b5383fede9524 SHA1: 10e93c8d69c5835768e6e89cfcc123a8a95607a4 SHA256: 6c891e9e4549c6dcb2dc1fdaae650d04e4af1b11d39a9e31a127c8f358deeba4 SHA512: 027b17fa4d57694fc0d05c6c3c751e0da337b871e418536ae4adca638171951d594e816f58d8031704e8dfc34cdb0d7cbbdd2b3c1ee342491d13f6e443fdac6f Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenohd Architecture: arm64 Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16506 Depends: Filename: ./1.0.4/zenohd_1.0.4_arm64.deb Size: 4040840 MD5sum: 529f08bab65c6a21da9c6f916b5cc6d8 SHA1: 0e6f55bbc891a4c465a43ae7831bbfdf47432254 SHA256: 540cb7a221dab8d85971301e14d04a97ae36352b12d87232fbd684db39205656 SHA512: 76461ac854b49dab11a226ee317d09ec0acc45ebd227c158c2940b19f96feb3928203fe336c5925e265c2629e8d6dffa7f84ea0336ff89f6c2a1e3be586fc07f Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenohd Architecture: armel Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17891 Depends: Filename: ./1.0.4/zenohd_1.0.4_armel.deb Size: 4396096 MD5sum: 7082de4682f995c3cd100d0a9afd96ae SHA1: 08cf9643630a843c6616f58e9ed53305d4fdfcb3 SHA256: e84524800ab1bfe97928cecbe0f81569285dc910a37219519b58ec46a23b3e5b SHA512: e582e425ca61aec8576ae96d28aab0a987c1a8b364fd35b410bc8cf22053a5c957ed1a6a86e3c3f4ca131ea1a898d1611399aee4e1b883c03b168822ffe6a840 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: zenohd Architecture: armhf Version: 1.0.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17669 Depends: Filename: ./1.0.4/zenohd_1.0.4_armhf.deb Size: 4452440 MD5sum: dc8756e333a29d476b517e9229c87584 SHA1: 7ed341f620198cb53aa43d5df2ddb47ddc84f7f1 SHA256: 34e529320a77570c011d3732c2eb01194d6da0dc334b48dfd0c6b52b0a1eef7a SHA512: 9d3bf2d6308f60347497fc6f5f3ff9636491b2e9ea6cdeb5fdcc074766faf0e3221021a3e6cd5abb62979832a2fc3e0ba51f43e92118254d2a62326964729afd Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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). Package: libzenohc-armv7-dev Architecture: armhf Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30426 Depends: libzenohc-armv7 (=1.1.0) Filename: ./1.1.0/libzenohc-armv7-dev_1.1.0_armhf.deb Size: 9336852 MD5sum: a88e7e50baa00e21300fd6489ce5f14e SHA1: 283c2e7b89de11698d1c334cc235d998b09351ea SHA256: dd38449c0e385aae8c5d5485ec0ccc06914944f53ad4cce4022e846e0e3beac8 SHA512: e9dc56dad4391d99ef157992eafba5ae03045e7c8d785524fcbdc9ef08fbd2aff0ef2024c4a89db8f9abe374010ad58cea9d35c5fb05c3e7fb974031b2f6217e Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18041 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohc-armv7_1.1.0_armhf.deb Size: 6868540 MD5sum: 436bef62e8169d9d895746233aaafcea SHA1: 2b0c4b1168216251664cd1d82e37478dff4fa61e SHA256: d4c12a32eef4bc89f2d78ce2532d4ac2a91819e7dc1791b99c06811070f6253f SHA512: 5406db7fdde0b8b9a10871ac759dc1bdf4340f5c190696338836e3b5809e4c601f7e02f429e88166cc456bfdff9476b3a5d912a589dd8c02099ed812c6e94fe7 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 38491 Depends: libzenohc (=1.1.0) Filename: ./1.1.0/libzenohc-dev_1.1.0_amd64.deb Size: 8936374 MD5sum: 60ccf7a177f223744ab961586f749748 SHA1: 6b78ea7398275a48fe240d5af7ddbaed4a71380e SHA256: 99f99c27d085b62dceaf17e3bfe03f89a96d3f77ee99ea8476ed20e98aa68be7 SHA512: 0906a96c87e1e4c139a25a3023d6ed3d2629416d67745c75a38336bc6eabb8f896594b1c039b672071ff918fc372b8b972597b725cd691a0ca9e9be93659e97c Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 38814 Depends: libzenohc (=1.1.0) Filename: ./1.1.0/libzenohc-dev_1.1.0_arm64.deb Size: 9021994 MD5sum: ba0f741ba0253ebb75a401da73314ca7 SHA1: 27da6b9cb7b0e6d94d509a6244cbfb032f16ecfe SHA256: 4f7a84d958e65b1cf85222a6d53a2c1ffb9957d17baf90d28ccc18fa0a2ab31e SHA512: f5185397bcf59803c9dbb42f86e6fe128fb33e7ccea54bdfe69d9e2ae2c65341e69dda3c458b86814ab654977a5bd18ec351100d4b096b5539928146223370c3 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31269 Depends: libzenohc (=1.1.0) Filename: ./1.1.0/libzenohc-dev_1.1.0_armel.deb Size: 9516602 MD5sum: 85f58b13fc27273505bf306172da1d8f SHA1: 73753d8154954803241ad2c48824b9d36ab64834 SHA256: 3f47d206b3150619c73c9ef4b0587b85001cd43e441026cdceaaf03bba61d6fc SHA512: 14c60e59bcd77ee440b664f4af5929222188744c784d12b083336d237b91eb238a20daeaf23e79e3cac0239295f244d1215533c4d737b3113478bb6c4502d16a Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31433 Depends: libzenohc (=1.1.0) Filename: ./1.1.0/libzenohc-dev_1.1.0_armhf.deb Size: 9613494 MD5sum: 706f5506097e4e5c7a20d0b9924bd737 SHA1: df5fd8827745d0ae38e701d6a2dc70da08d22cb5 SHA256: 4e8049baeb514cc51d1b9ccf9ce71b8c985e5f54d8f1b64be368946360d1c2a5 SHA512: 9a699946714c0acb943e395bb08f30f51f9e87496c6fa4e3297dc6f390cdfc90089ef5452937d19e47dce227e51a73cde0fc0b751a3ea7a99615ef78b4ee03cb Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 34364 Depends: libzenohc-musl (=1.1.0) Filename: ./1.1.0/libzenohc-musl-dev_1.1.0_amd64.deb Size: 8697080 MD5sum: f0caae190967fe6bde905edb279e9b80 SHA1: 158603d3b3b1782bad0244f4f6ff3963d3e8e3ec SHA256: dca717271c954f64c998085e23c2f3ec5e833eabd3486f15cec5978de860b0b1 SHA512: 77d1b8af47047f33c042f4e859607f7de502bb23ffa69150058f489c356ba6349a33b888ecb4b4215209dc870bc149260dd1c0b07c2b017787866812acde2c22 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 36828 Depends: libzenohc-musl (=1.1.0) Filename: ./1.1.0/libzenohc-musl-dev_1.1.0_arm64.deb Size: 8764088 MD5sum: ac7b8d4b0f27fbeb51f63f1a08819c86 SHA1: 8d8786d75943693c8978b4b7afe9749e434e486b SHA256: 0e01a1b5b6cb74ba9ac3cee27a421cc0967486c6865ee8bda7e25c3d90adeb05 SHA512: 0dbf3c7cae78032b7e223f709f2b252c68042c052d512e38e207d44e1d5b78481a02336af143be93272833459fed0f0db36a27e9be16c1479de899cb835208bf Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18174 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohc-musl_1.1.0_amd64.deb Size: 6589060 MD5sum: e5f7f20c9a0409d38b1225d5fe77d5a3 SHA1: 19b971690686684f7764bb9a8e2714f4cd91570f SHA256: c0f7500e6f1424839e90e297248bbe6c51d39c271693c4e38aa1674784c1d2e0 SHA512: 55c47ddd103ccebba31380848c1ceff1e69e8c4026e2c2f9594677f226878ae85edbfd434d5a0da0b714ba7ee7fbb3d0e8b95d204477999f124868de74232012 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 16869 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohc-musl_1.1.0_arm64.deb Size: 6272378 MD5sum: a098e8e3648b00cc7ecf6bad7e5e90bf SHA1: 9535bfe45d88693d0f8ed219a7271df443db3de4 SHA256: 0a3e2c49df5a1a1d5c33e889a681dda4f195650eaf96830f6fcdf63ff883f2ed SHA512: 1414be27b441f87f13fc9f6a293d6533ae207fcbc28cedc87bae64da7fbb596260eef116f20daabecd38b3b085d3d0e282e3eff6e594f9c567cd409bc73f7d7a Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18760 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohc_1.1.0_amd64.deb Size: 6607848 MD5sum: 5066ddd8f3b5c08264887bc68cee4d77 SHA1: 29736e8ecef86ff3def4d23397f76e01927bbd3c SHA256: 73c8e4edbf1fec739dcf18b57a53a97ee8d5bde2ee20bf35fceff080083b41fa SHA512: 4ee1380b6bb477c243333306b086811a9f9275a1c6f5bddf9aeab94f9ca11654435acc2f726875ebcb214f054e8baf3d97aa34ac49ae95c5aee888bde4af5f09 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17219 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohc_1.1.0_arm64.deb Size: 6331140 MD5sum: 19faccf037a2109f2a7fc621e123927e SHA1: 9169bcba59debcf69a6f69c99d4dfc75999df915 SHA256: 217d7d2342c671b1e8ea3eb9f0b164635409d4b60b3997cc5990ae197a4672ef SHA512: 44b23fd71a4515d2cd66b420e3bce1bf319305fb4f92244e923e4b926b934eb12a488494cced0af834d03675bc46449bb84fec13672f4add8d1b6d62c04bb3f3 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18443 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohc_1.1.0_armel.deb Size: 6952988 MD5sum: 8ef072de348a3276e25941bc23e24979 SHA1: eaf7a735e9c22bd67f13d1e8723a34c95e35b557 SHA256: 33dc4ec47ef6bd82d90aa00bc87a13860475e79c4aa06fae61eac47b2590de38 SHA512: 9355832e5fc117de3ea7c084b3d634f172a9b7c1cb3bd4d3cc125a034257afbf2e53de7fb68f6e3462944c0358de5a49a07a4e06ae816a39a62586abef2c6572 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18427 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohc_1.1.0_armhf.deb Size: 7018642 MD5sum: 063ecbcb13c492eee40bc25790579504 SHA1: 985ac575403c4010abe7d8a7540ce67be86c79b7 SHA256: 37962a0caf319f06954e5f2547fa356d21de7bbf26c983432239e8aff682b12a SHA512: ca88e3453296ef9f225dc354042f3f2d3ab6f341f312e12e3874770880f2abc1cf335ca5008a9a40cb81fe85ccc2025292206eafce683a5a62b9e005552f601c Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 378 Filename: ./1.1.0/libzenohcpp-dev_1.1.0_all.deb Size: 48340 MD5sum: eb94d4e6e3b9da2780c51671232d7956 SHA1: 223479a31f360f00dae3c6fa3c48416b030a2039 SHA256: 535404c579b9fd632b8948fbb79c4ea661723410283acd6611f4508c643c8559 SHA512: d18bc008b5cf129a00cf37620c6f3eb94dec73ff7a69ef1290086c357bdb8060057649bd58dadc237dedfffec3724f2f4ccfaf5503b5e58448df43c28b7ebdd8 Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1154 Depends: libzenohpico-armv6 (=1.1.0) Filename: ./1.1.0/libzenohpico-armv6-dev_1.1.0_arm.deb Size: 230646 MD5sum: 9424031560248e15f61256609b8edc90 SHA1: 87f67e217a0c4a94f037e45d6e6dd817ef9c8d22 SHA256: 2ddda30acd40c28e0a7d5cf288314469abe9006a71645dd05a92321835507b8e SHA512: 29bc675c3d7d3797dd5b8ead93ffb2522cbf2902aa3fb6d31910a9f41a226246ff45cbd21e1d3a09c4673d06a28f49891835f05e36a43221ee6f1780a79292d6 Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 338 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohpico-armv6_1.1.0_arm.deb Size: 137908 MD5sum: fb7dfd96964bfe5c8c77f434f18d2863 SHA1: 0526a165db1407f65df432fe0b7376b50a846c04 SHA256: ef63e31ebf9a1646c1f54f3bf414251c4b9c9a7ab212b2b191c6a2458d0c1d7e SHA512: cbebd91b6069e9117390a50cdf94ad774f8b3c1458dbf564c6ea71edf932ba60fc06d3e13e232068634f1c1c21849d771f940296360fdc1afd3c9310f2ed3eb4 Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1147 Depends: libzenohpico-armv7a (=1.1.0) Filename: ./1.1.0/libzenohpico-armv7a-dev_1.1.0_armhf.deb Size: 229348 MD5sum: 34c6bf44c8b3feaf9dac3053b7f1fb93 SHA1: b88cdd394729bb3b55efa38d1af81eb299b8bed3 SHA256: a904d15f70eb2b138be49069a8318ea39235cf3e8a8242f1ecb7adeaf66c5d7b SHA512: de6ec3224681d397438ee22ffa36b33c7c2de24f3e09f07aa7dac1f3e6610782bdb647df109ca018eaea0304a08bcee604c61eada0bde3d641ceb5fee5f7390f Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 334 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohpico-armv7a_1.1.0_armhf.deb Size: 137256 MD5sum: c11f1d58889ba3f43192d0d75e79bce3 SHA1: f68b948b54bc7dbfa50e655a5ca59f460ee9635a SHA256: 9ebb617076f32003683251b67252df5d93de7ad7225ad7ec196056c20a118fce SHA512: 6db225a7615d25a7186323d07d8df4be32ffd8d8687fcb93825cf59f88b69deb4fd033f68d9fe836dca701dedc6631d4c065fe90d1b91fd4be505a84f57365b5 Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1389 Depends: libzenohpico (=1.1.0) Filename: ./1.1.0/libzenohpico-dev_1.1.0_amd64.deb Size: 275288 MD5sum: daa212108eebfd47d4eb05a14b8017f7 SHA1: 1b962232d8745c7a969cc35a3a4243c8679aa536 SHA256: b120eff79bda365b6e4d08a3b19ecddf653e1e90a9a5b7b8a56fc577f8cc351b SHA512: afd404b976984005ef684d74864be4137f6fe27e67f7c3976374c47468136b597d063f08414b61ad5bb8698afc4eab02ea38b5ef9f0256a46530d5c706122ad1 Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1153 Depends: libzenohpico (=1.1.0) Filename: ./1.1.0/libzenohpico-dev_1.1.0_arm.deb Size: 230262 MD5sum: c7ac9e176d88cea493fb0407fd0ea328 SHA1: dee000aa7da9107ff78879500c8699b7b7d46ecf SHA256: 651099d4b3520f9ce8379e86c4c75de2b71851c160de2fef4cf57cf1dd973f8f SHA512: a1e53f5866440666f1b39fbd3d69d3da828e3922785226a3987b4a0d4f5de1e307b689e9cd3b22258b9aec8cba75488a04e0b493d92e9bdf5c98f9babf3abc55 Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1399 Depends: libzenohpico (=1.1.0) Filename: ./1.1.0/libzenohpico-dev_1.1.0_arm64.deb Size: 272022 MD5sum: f1d9db15d83a38424f300b0ee18de3f4 SHA1: a050758fca578ac305ac6b64eba7ddd30ab5642e SHA256: 65156e5a6850984639cb5de5dd79268886edbb62743cf2bc0136bd52c1a5e51a SHA512: 93b4a2ae3ae13983e90768f175fec5dc7db6677aac73f352fd50a4d518b6174ddfcbf7354f5a9cfeec4641764814b794c47d90e3f7eba038d4c46848285bc756 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1148 Depends: libzenohpico (=1.1.0) Filename: ./1.1.0/libzenohpico-dev_1.1.0_armhf.deb Size: 229084 MD5sum: e6924dc76cc23078443433e0d686349d SHA1: 025771f731e5b51d08f974e1cb289bf3805eb92c SHA256: f876bf72a51ae82b8ccd58998927f075f62dc56472496f1fd749b10f39b73e0f SHA512: 8c4e5af532594825d874d0cf05294438934fc7ef5d57ec6fcb5247792f8eebb239dc15629278c6cb99405be6ce1531f4f5fd0db21f343afe686c3f37f847ab22 Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1362 Depends: libzenohpico (=1.1.0) Filename: ./1.1.0/libzenohpico-dev_1.1.0_i386.deb Size: 299552 MD5sum: 694391cdea81c78de3c7e4e35ffa4558 SHA1: 228fcdc34240c2c3c8d75031b7d84f5a5d217ac7 SHA256: 632a59f4af95a5f2fef94a3e64e26ef4ed2e84f7851236225aa7e82f2c9fb3b1 SHA512: 170bbde9f0ae031dd59ea39bbbcf60336fe8f944a8a46127d08c00b8b8c9b8fdd66334f2135f831a9bb004e6c57ee7e18e939aaab79cace2e563c8f108127648 Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1292 Depends: libzenohpico (=1.1.0) Filename: ./1.1.0/libzenohpico-dev_1.1.0_mips.deb Size: 260334 MD5sum: f52530cedd98f25559f281c61b9c543f SHA1: 4b252f54e7447fff67096addd62349fee0be99e8 SHA256: a81decaf1f3e3283cb66bd13884b793582b437b1f4971feb6cb9641ab976dacb SHA512: 2e9a4b0c8878ec9370cd6f3b33191c6335dabec82af19cda34e76900624d1cd53de5e2175609a802ccdab5bd341b3a16efd0feefd8738ff0fae426892731945e Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 457 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohpico_1.1.0_amd64.deb Size: 168896 MD5sum: b318dddd4944a9d2b15fb273e013c244 SHA1: 3b63f878b4b8906d1472fa08119d2bbf7508f891 SHA256: 04906c1b7e07a577a2674c1b528d21f04f9a78f8da92d3730826ec39e37b586d SHA512: 5a2a7fb89383cf85cf86dd72e93fc64e0c8b26e21365c8d5cd504539e4b8818687575ca622470e9cbb0274616e899f582d0cf61377131242461a65da84b66613 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 361 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohpico_1.1.0_arm.deb Size: 146166 MD5sum: 45a1115208c29faab86c74054e71589c SHA1: cd9fe06354f1ee12d7bc35b76e4d77f00f7e8b96 SHA256: bfe5e772f6df54282133f95468712bf1183ab51ed337ab62a307ab4a435f83dd SHA512: 17dc829804add564227813349cc3e6f28884679862c0bcd9fcc3fe9e81fad43a10839d25cc903b15f6332d77ad8d6791ad9e54982aa7fe168c05d3ddea0d03c5 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 471 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohpico_1.1.0_arm64.deb Size: 166848 MD5sum: f88d011c7b203814cf39a27a97b1af36 SHA1: eb97baded3cd290ba7498e8f1172a1e343be990c SHA256: b946a1fc400e7c62fc34cc36812abb9112fa584d7cc0a07d2aa54e925b775c1f SHA512: 6fec8c332b56ebe46e4f83fc74f2e26d59bc80f22f3238725e8f5a6f992c8d688fc11f5856d72f05d2641e493f2f53a4e53b156eaac972095fa260390951a194 Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 336 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohpico_1.1.0_armhf.deb Size: 138524 MD5sum: 1ce99ccefe095d099a08c8956bac91b9 SHA1: 2865399f5cb9fe9d4edf87d08db39f7d3bd7bb11 SHA256: 26b4b5c489efae538e1645ecad7a4582d2f5107dd4e02c476172aaa9f25e0391 SHA512: 582a4358e578e5cd891a7f0ec3cb2848ed658d8d53a2e40b0243bec6c42bc89f11e88bcc61e0277ae5b3ac986a7cabae664136610753911b239f292ac0e5e878 Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 484 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohpico_1.1.0_i386.deb Size: 191396 MD5sum: 175d23f3a37579f8f9d5c5fc0005880a SHA1: 721093a68e0a17a1f8b7124546d63c07f6732387 SHA256: 1f382fbb4e828e887ff19cc3034073ce1b3af17d23674546b7deb9f1c235e8a6 SHA512: 85b36004de1538da9523cd5c25fcaef5f719a44cc9c99587a48ae0df914fd6b322d40be9021e1ce5052660ab176da6ad4a06a949dc6fcb1123c58322b9457896 Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.1.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 438 Depends: libc6 (>=2.12) Filename: ./1.1.0/libzenohpico_1.1.0_mips.deb Size: 150716 MD5sum: 5cecccb936f8a1871cb20415152e619f SHA1: f6f29e7b08d7514111e684ab1865c4cc1cb8be20 SHA256: ad413e121df49d54035b7e516e7c087bea1b52e67a93ca944e323974100f1ae3 SHA512: e1919572e1fcae38c124380aa692bb44bfb74374dfb7402d16ba9a60a7d6b6449074c75e10dc92d45913f6c5ba6a8af3bf4ad83a37f73e48443283c161cb66e1 Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20840 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-filesystem_1.1.0_amd64.deb Size: 4600304 MD5sum: ddd9909600d9b86b31a12de17baa76f6 SHA1: b2bd91824a0302ead8955d0f5c85e5c2337ddf40 SHA256: 8eccc439b75c52ef6faa33f527dce7f3fd16796726e5d09cf69ce99f17d2a4b2 SHA512: ed5d4be0af88e01f93dc68eb9985b063bdce3658bc98f7458fce511fb24fad5394205feac52346382953f40bb021a982474b521260d3e52900ef7ad48f1fc6bb 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18945 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-filesystem_1.1.0_arm64.deb Size: 4140148 MD5sum: b60f56d87176c3b4f5a9ba8c4169fdb3 SHA1: b92a5ee3145df4bb07e48aa084312da18eebd10a SHA256: 7484cfef9318ea4565c9c87b9c725584011ece21c6c305b444d0284ef07c50d6 SHA512: 37174b7f995b6ae5ecad9740b62a3e0e911a60348888817cd0410dc2e42d70d4fae8421f34c9de34a3c1bdf1b8a25f75f27a80bdc2222acf1d00b12a973adafb 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16513 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-filesystem_1.1.0_armel.deb Size: 3909840 MD5sum: 5d30d91dc78f04bd667aea89047c13c4 SHA1: 62138d552ed00ee5b12b675cc2aef3d01718fe7b SHA256: 91c1cdfa3376064c7beabfbd8429bab2ddc23ef03f89d6fe14eef815a0f83680 SHA512: 4ce24f7629bcd5ae706a45630e86bab9755378a6c72b698b2db1c9eb577fa04ac292bcb20eb89e83181d08b0344210b6553595d1dab398a69d9a4656304015e7 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14629 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-filesystem_1.1.0_armhf.deb Size: 4009416 MD5sum: 24e0145cceaa3e04598ac97e128a9cab SHA1: 74cc38a6957629d970bd3f473b766d6a47456cca SHA256: f13adddc086a35451914ac0827f3fe7d759b64cd48e4122fb3116789f969a67c SHA512: bd81530683056785a780be381ac95f467706707fd69ddf291f89eb042baba780e81c581267a940a103eef0483e56b4fae1701f6445658d35a626ff512b20d001 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15712 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-influxdb-v1_1.1.0_amd64.deb Size: 3127764 MD5sum: 94b9e282d104d7c5b3d86729d67a1194 SHA1: 05ec4072bf95a2fa53ef17d95d31aa12962d616f SHA256: b830c3047f8ea5928a0959eb954e7613481ecf003540f75fd40d64138fbabad5 SHA512: 15814a92fb34fac9d6fdacbd1c6b19f9d1503ddafe288f66c1b10c8289dc4350d520bd102fe26d715bdbeb7b1593b3a80f241d3fd488066cb2c64cdbd4785446 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14028 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-influxdb-v1_1.1.0_arm64.deb Size: 2814440 MD5sum: 8e19ff0feecd8d99b1f47fa4c2a5b076 SHA1: 55733ca893323ae9896462022ec6e53c602fd6b0 SHA256: 03e3a203ae3c611ad72e24fcb2431465189f099ab38198694cc4bcd9fe90c38d SHA512: d1700152198f1e3b6c7ef4087c09ac1c2b47c975258efc7f5e981d4ddacd233a631af95ff99efc2294f24b6bd0ccbbc1cfb199cc8d7ec50daf6d260c1a9535b2 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11805 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-influxdb-v1_1.1.0_armel.deb Size: 2552012 MD5sum: 7fada749ba987dc4e691396d82661d3f SHA1: 24d8d62d0ce915a7875b579c9907314b1bd1470e SHA256: 159a98e5e8741a9293fed73e1fa7f49db2126b039dc687eae9e2a40d73160a38 SHA512: 5cedcd6465d7bc228244f4efb273d51afa598a789909554817160baec1f14f04f7a465f9ae5105be2460d2a10dbfb8cd1bc931cf4ca90157353d90e89f556922 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11682 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-influxdb-v1_1.1.0_armhf.deb Size: 2543472 MD5sum: 97336a2749b691c951d71361a4fefc56 SHA1: 0ffc08a35226fc9bf55207de2ff27b511c0e3d49 SHA256: 745dfca784ceaa3c1171dc7b014b2fb62b242db389984b1388e2c597a155bebf SHA512: fff20f02dd23702e09b75ee9ed1138dc4cb0cd0fd4df742aedaf7cfd7ba0ca493fa99340f22f7106978b7cade917c0222973118c19d15154b3ac166a7dc445af 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17303 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-influxdb-v2_1.1.0_amd64.deb Size: 3804828 MD5sum: c00db0a8c77359ad68f06be49dece654 SHA1: e0e1ada1116ca8723587347bdec47ae40201df8c SHA256: 99839d3ce159b474a40e7eb636667ded42714c120819c1f62edb4935c77f8da7 SHA512: 28fe05462f33fe93f36942d7a45516cb1ab68b9b7af97691161ef1343f18e473513011d8d7699dd27ff7b95e8235fa288f37b9f18a08928eacefd003e38d0028 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16256 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-influxdb-v2_1.1.0_arm64.deb Size: 3487044 MD5sum: 181033ecabcd04fe335ff3b74a5c6c1b SHA1: da94b7ecd5d0b611ba7e825fd810b1589a9e20d4 SHA256: 4fd54d3e97102da1866bda13ee5bc3c26ba89f1030885bc6ae683b5dd741872f SHA512: aad7e52c67c93c87356b9efaa93527f183c85e15b13ca7573cffb70899300cee02b2ed781bea4f2812a8552b8812918eb09543a4f982b8041e74d7ccbf346f1b 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15595 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-influxdb-v2_1.1.0_armel.deb Size: 3467444 MD5sum: b95ee154ed2d2837b1183a60e86ea427 SHA1: d650b0f44cab223cff6f633fac9b3a798d122363 SHA256: de74daacc3eda6c3759bfac866de4120a8055c11ef7f1ed67d7151a7a83977ba SHA512: 183b881eb694604ee2725b20fc74ed38a513d1bc2691a5f07db36bdbda46563c5d4cd5597f88213f763875de575cf90d917cdc27f9aa7e16d48bf82210d79897 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15490 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-influxdb-v2_1.1.0_armhf.deb Size: 3514096 MD5sum: f1b903c0ec84347204158489c61ce6e4 SHA1: 0a6b9f2ece6437fd1fc612d622283ea2937f434a SHA256: b6100011975c8d50c9a5ebb74b01d7ee5325d432ceb5939a4fe89309f606ff21 SHA512: 78656625acf8d45261afaeaadf9b3afa25fe080df2982775030244dccf9d3995072e51e1f3c078a5937ebf41afd9bdc651e3bc7a4c1ac3af19d5df2714c6d40e 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19388 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-rocksdb_1.1.0_amd64.deb Size: 4328124 MD5sum: 8dbcdf4e80a812210d8e1d50e97c57ad SHA1: be11840fb652addd9a9be9f65db49ee87840125e SHA256: 25f8cba6489454ac063582f148c68ca3cb5fc731c5cbed3102941eb28adcc6ff SHA512: aaca6e7db93401d79bec106505af8ecdef2195b310b36e19eb0f9c3173cbb9cadc4bc7d2e84c3a308c2d55caf9bfd6389201cbf4a0f5ecf07f6f55bb24b9efe2 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17494 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-rocksdb_1.1.0_arm64.deb Size: 3888912 MD5sum: 2f03ad44d191c3a0d2b9d87a9d776e58 SHA1: 9a53f78ed8a8062d9126b31d94ba4d750115863c SHA256: 38e2484decdeee61b4207e32ad0fe660f2f06a2f976d643cd0c8d436be06be3c SHA512: efcc326e1696f67a1abb916dc25cacc4af37c3c9b1ca3d3494dcb9525f7a5ea7180e6197e9cac21784bdffbcb0a49661c7d9401cc881a4fbf2a20e1efffd86ae 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15307 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-rocksdb_1.1.0_armel.deb Size: 3701052 MD5sum: 92bd8ff900b633df024abc3abf7446d0 SHA1: 5ad9ec0d168417fa0aa100e734fc977645779b66 SHA256: d9574cc6ae7e94fa53105c009ddcd41575208ed786050a1f7da828655cccc62b SHA512: 552e5c1b25411f756be20ac94bb9123684823f7b51a520d0f700405e0f06a4d530b09f2a7cfbdc426a6f4707d2f0812aa4740717b5219684b087f435240f0155 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13400 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-rocksdb_1.1.0_armhf.deb Size: 3799468 MD5sum: 9052486af3aeb39086883f2035bd850a SHA1: d68133a446ade8838a0355bb3349cbb1908117a7 SHA256: 73a28d03a17fce937f4dc0937334aa350eed715284ad331bdc68eb6beffb7598 SHA512: 24f37ac983ea9171e6e78a0c713b200f280b4ce859403c17b302ab7bc84ee99402658287516502437dbdbf491f4bbf23cf44750bef967dbcf8103e0d9172e101 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27266 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-s3_1.1.0_amd64.deb Size: 5514452 MD5sum: 51e43951d12c3626da534fa07ff7b9d9 SHA1: 3386b7f4ba1ff4af1116b279d561f73cfdf3e840 SHA256: bfab93da7180812ab34fafa12c33db5a866a608cf87c5bd14907668869b41703 SHA512: c565dcb7746d0f70b98a28188d83693c8ad4f828558cdcbf51627e082422c6b3bd8a5ac01cbcf6f5d48e5189fb645f605f460a7d47ef07340b882cd2d6994657 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: "", secret_key: "", }, }, }, }, }, // 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26491 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-s3_1.1.0_arm64.deb Size: 5231944 MD5sum: 6b5607f652296fd9518603739e7b5292 SHA1: 1082676a6156254f1136e35f962d52454c2c1f32 SHA256: 8dc80fee1f9b7600865c6224f48870bf22b01c082d9487624cdcbac76572d96d SHA512: 9a0796f20b142b0363a9e74d1064a6e61386f29a5f69e12216b1df38260654b9d40a01c7543c2c0748b307c4c423a7d9ee4be79ce9b4f74b51cecc392983efa1 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: "", secret_key: "", }, }, }, }, }, // 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25169 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-s3_1.1.0_armel.deb Size: 5093784 MD5sum: eae93159913bead53f5cae0a5b81e4ab SHA1: 0c84a5df5c644bc950b49a67b718c058b0ed01b1 SHA256: db52e8fe4e63b1aaba8aba2dcca078c04bfae289ef08196e6d996e3e106fb6a5 SHA512: e27d07ab04fcbd86ac9f37ad34a59b2787754fe93074f026942f188fdf8698bab50bd558a1af3547ceeec727b854e2079ef74726d3b28c2f189f5f69ce19a197 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: "", secret_key: "", }, }, }, }, }, // 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24957 Depends: zenoh-plugin-storage-manager (=1.1.0) Filename: ./1.1.0/zenoh-backend-s3_1.1.0_armhf.deb Size: 5142468 MD5sum: 29a6f5e29fb0bef6802981beeb9ddca6 SHA1: b540ad6cb7a4402d27898b527f16d77c7c21b545 SHA256: f81a93bbf70a26254b2b15583351fbef3ccd8200bfb1a238c7bc379f7f863d80 SHA512: 703d913eb171102ada7aa4763d63eaed10b89a95739e4ad40ab458517457e3291f5a7ea0a82c82a46ce6c4128cbf72dc85740c49dee240b540c273e68f5759b0 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: "", secret_key: "", }, }, }, }, }, // 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20962 Depends: libc6 (>= 2.29) Filename: ./1.1.0/zenoh-bridge-dds_1.1.0_amd64.deb Size: 5354764 MD5sum: c39090e506d6194551b9dd1ce3cd552c SHA1: 4e20d097673649d9811cd4f7b25ccb74b148212b SHA256: 224ba81ad7af390cb9cbb7effde25e01e1c30a314d3c9614bba5a41d37d98094 SHA512: e54a57cc080a5aa2f3cb59ffc0f5e2a589039839706f37a1f7833be461f48ca14e5c877f8d2a4fc6a9678981b0da2ba68780c7c65e83d9fe10797a023d56cc29 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19131 Depends: Filename: ./1.1.0/zenoh-bridge-dds_1.1.0_arm64.deb Size: 4833492 MD5sum: e9aae34be4786120cab3218e334a327a SHA1: 1106e52703f4708516ef65cec12baf780bdfd324 SHA256: 96a89ecf6a6fd77e3c2b29f7e4bd56d5f372e9bae261170a33914390ae2a9f60 SHA512: f9234fb16b59d9c5cbb58d155757d628a6cba3d571de04331a2353425abaab0fbe264a8f9c4561a8afce9308b268b16465f76744cd0885856c4bbbabba7a0862 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20344 Depends: Filename: ./1.1.0/zenoh-bridge-dds_1.1.0_armel.deb Size: 5116652 MD5sum: 4bf8c19e248a17db830423477ff8cb7b SHA1: 410aadb5158a74d7605ca6fdad9a1f16107d1ee9 SHA256: fb1fd10aeb312bc3ef8394f2715c6220cd2454db21a4ae94fbf9ed2f1201bb28 SHA512: ca838b517fff115e46f9b570530f6b9b17a1e6de8b823c86f309f0dacef371ab443dc954151b8a01ebeb76139c0c383a1278b311a601a5c16d20c44b629cdf70 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19823 Depends: Filename: ./1.1.0/zenoh-bridge-dds_1.1.0_armhf.deb Size: 5166936 MD5sum: 051592fa8714958e88a89777ecc7c50e SHA1: 067238eac5ec8ed78a7108e842648b106fcc8178 SHA256: bdecec9f47886555bb3fdcb0c23339e01104d6643013e24045432456ce56e27a SHA512: a0f9a5f5137550232bbd654260f022ff4df69167d3e7ba691338080dc582eab70df6b1afbd59a1c2f8be032f7e100afa8f4fa5701ed2b4aff534eb726a988221 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21253 Depends: libc6 (>= 2.29) Filename: ./1.1.0/zenoh-bridge-mqtt_1.1.0_amd64.deb Size: 5041984 MD5sum: f9525f95bb87ff525c0310dc089446d2 SHA1: b7291351e48980dfe1462924c581847f48cb7c22 SHA256: 0048a4f8215df3496b34a66b7461582266a29f84a2c261bd5eed88a9c0bb505c SHA512: 7baa17af939ae46112feb77a203e366ff8c1b05f15d0d002c83304a8dc054391747cab8c7e99b74a2ca90e14fffab55851fdb499ec73768567ac9a7c0e66bada 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19466 Depends: Filename: ./1.1.0/zenoh-bridge-mqtt_1.1.0_arm64.deb Size: 4560180 MD5sum: 7107100d196f225be3770fff4bf5c8ea SHA1: 24413d076d5e6f633f195c3a62357fb26bbd6ea6 SHA256: 18c1fedd63a6256a496d139fad420972efbe05bdf5e238f5d3cf6d17bb0dc759 SHA512: 314885966c3ec296f043383168f16ec453d09877cc653d725289532fa56eef2bfb1c377ffef76129ebe9762405f9e01c6cd075662fea4f0078ca841105951f47 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20672 Depends: Filename: ./1.1.0/zenoh-bridge-mqtt_1.1.0_armel.deb Size: 4848064 MD5sum: 64dc422891bbc702e93c2d3733fa5882 SHA1: 92dc02e3c48fd508b8dfddcfbf5be261b0d73eef SHA256: 18efdbf374a8dd858959b76544f773cd137dcfae368163bcce2de7963fd0d105 SHA512: f4db1f5fe62bb3dc4bab9bcbdef64a8cbc149e4a8dfe10e73972b023a30b549cda6bddd03af55e9432b2cc5b2fc3286cd39698343c32c332ea141b139dffde39 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20392 Depends: Filename: ./1.1.0/zenoh-bridge-mqtt_1.1.0_armhf.deb Size: 4877684 MD5sum: d3af5ecc4604a4b0c4dce20c25166779 SHA1: a008069d1d088059a690b30294ca8d936efe5e86 SHA256: d35cfbdfa403a1f235df542815c174d6c4dafeb8efd6c0238629c0e23914920f SHA512: 28a8f7c16bc211106cf27417fae07738d6d0c9065139c7e70c4bea051a0c7ee542151e853b101fad0265de50f11a6bfeddc0448c4bd40b9a7f125a6ae8187fa9 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-ros2dds Architecture: amd64 Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21568 Depends: libc6 (>= 2.29) Filename: ./1.1.0/zenoh-bridge-ros2dds_1.1.0_amd64.deb Size: 5465660 MD5sum: e2789b083b994934b7a4a9dd9fa417f7 SHA1: 44683328a7ae7f828a8f195ecdff66bdc4db4e39 SHA256: f7ed8665e237a480485bf202a3895485b04657b381220daa4a9754c15ee4a914 SHA512: 30de55babeda25c91bc7e5190bd2fbb35ee3662cf0c6115b6acdafa6393aed4fbea210c4789f674f093f36ed7a28714aab12354a1b6cec22fcf33b3a0ad1084e 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19693 Depends: Filename: ./1.1.0/zenoh-bridge-ros2dds_1.1.0_arm64.deb Size: 4955444 MD5sum: c1a8b7ef1f22a0a671dd2b8e41510300 SHA1: 28c1e0f3d701f9a64cb0e36f71afb2c3f29a1655 SHA256: c6c5e2bd56fbb8c0b93b7020c97be3772796667e336ea59213842ea54cd9dd5f SHA512: f32ac2d5b59a24e6e29d160a94c243206b9b9c64c0d788c49fb02cc49ef319e793619d825c267e28360c0ea4419a5dc6223bc198b9448bf8c98e2ffbdb4488a2 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20924 Depends: Filename: ./1.1.0/zenoh-bridge-ros2dds_1.1.0_armel.deb Size: 5234860 MD5sum: 1824962fa710e57ede4d721ea46ad37d SHA1: 433afece4ff2747eefa0b81fef560a4d9328e8fd SHA256: f20cdb921d1a3cf6be18c992ba4d64ebb61b06905202c78c10167bda17bc5b9d SHA512: 8892ca060be20afd16b0297cf3ff052ed0a9e044f1689b88be13d7f737bde8d720dcb48bf0df8b9ab8e925df61a01c66b2683f5ddf6863da147da923c9212eeb 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20408 Depends: Filename: ./1.1.0/zenoh-bridge-ros2dds_1.1.0_armhf.deb Size: 5291992 MD5sum: 607e5a4f3c132bd8c4fdd94ffcc1ddbe SHA1: 18a185ee2afbf692fce723639844b38fe93812ef SHA256: 3e4ffe5b0a5a33e18780ea2c29e48c75d1b72b3fc3be9463eeb8ebc97662cbb8 SHA512: f41be6adb392eed841f2cf2eda1071c531d19e953434259a8c7c5064d75aa88073a6038ac166c50228b9d87d7415957cf5c872be45b67c8bc37ee73a4c3b3a84 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12854 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-dds_1.1.0_amd64.deb Size: 2587596 MD5sum: 5de2bf83d2733916410651d9eba7235b SHA1: 8e77c7d994965872128f2909ede29b96e404b786 SHA256: bb1dbd2cefab91529650540770b688193514250ea66045249f4ade9297f72d80 SHA512: 2e6aac8fc7e1fd916394874bcb8ec4f7ec467a4561ecf3c6985adfbbbef5b6e96ea4d850fb616ccbc6b8d5e6116f18609ba492e6c7b858c624a010419ff46e83 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11613 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-dds_1.1.0_arm64.deb Size: 2349020 MD5sum: f1d4e3d5b2ea42d72f843a613ef42af5 SHA1: 46ea5d48db41691e652c1eb3db95f851a419c289 SHA256: 730ba8a88d7d0d76d75706016851ec7d9eba4d1ca75fcf450469f7fb6ca07cca SHA512: 11034f824dc64a2793cf4955a9080d59990b225318bdc062e64f9ded457a13a78c69a18330e499d49a972ae240c5d095d551f2b295e2d2a063328103ac2850f0 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9683 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-dds_1.1.0_armel.deb Size: 2199016 MD5sum: 08e957b94354b26d668ab8d65e3ae84b SHA1: 3f442b823c3a5f5bbd4b097ff6c442c9afce7d10 SHA256: ba007e072e38cf5ac2fb98d6ca194be31b8bf81518445513fdbaff443d49c2f3 SHA512: 1844578eef69634d790f753a86b1abe8fe525fec8fa3e890139d32522161305a94c02bf965cf707bf68529f50925d2386210bb988cdc0358fad3adb47b0eb77b 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9304 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-dds_1.1.0_armhf.deb Size: 2206468 MD5sum: e47a77f4e259d0e0334088e917da8293 SHA1: 59b4abb2f6ea9511113279b0e759b6a003c71275 SHA256: 5425957a99f0dabe3422550f95c8df72dddf41631d6f08fbd6120a8ed7bb5fe4 SHA512: 8e922251dc70cf9a6c544bd52e89da2ffcc4395230ba5a9807a61f96b6dcefa300e79c5ea3a2a5d63b9c27b49014f75736f93f414edb5779102fa2f816b274e9 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 described 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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . * Shared memory is not supported on Windows systems. * When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. * In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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 information is 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14115 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-mqtt_1.1.0_amd64.deb Size: 2892364 MD5sum: b0cde3ab5eab3d77a82fe0848b0ce8a4 SHA1: ea5b73b39c99a4f0c0947d1f025564c27d6e375e SHA256: 97a37bdad7297d3fd0c0dd822e59824985e2af06faaed40a5f993ac89c6fe7f5 SHA512: 3aeba1c3bdc06dc31296ddb5566716b47707caaebd4747087c7690537248529e2d1be572083c2e8fe41afe7a97d3afb931fe58e7c3e384da1b391e68a66659dc 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12836 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-mqtt_1.1.0_arm64.deb Size: 2587356 MD5sum: 1576333e4b45a1d008832bc19f05af22 SHA1: d3ada93dbf1e3b7e8ffb7be818a047c0d8f7cf6e SHA256: 75071408a7be2c67e3b7f5a39e296d47e52a2adcc491617029f214afe31f43b1 SHA512: 8e29202ff9f2266b476485854f897bce927d602a720f1e9c59c5e7b05ea46b00bb0a310863c28933656e636d941b19e3a37cedd1589770938cd3ddbfa68ca565 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12831 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-mqtt_1.1.0_armel.deb Size: 2653396 MD5sum: 872b5a5f99efc88ca58e859497ae882d SHA1: 768b0f8c8b8f1637904a12e8e08791ecc8aec924 SHA256: 3abc24fb56475897abf686c504c8a865c0b1ced08070e3da76416cee87acbeef SHA512: f980c79f5fac2630a35d036217968d14aa208cdb9daf9aa4ea1f3543b37b53bb2d02f6fcea9fa641e42d95c420cebf75f05bf3eb61ddce7bcd865886fe1bdb92 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12744 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-mqtt_1.1.0_armhf.deb Size: 2694324 MD5sum: 3d4d361e6c8956e68b5f6926193bd21f SHA1: 7b2b57abaf39b13ed6bb731d3dc79d8ac3327886 SHA256: 007ab68b28356aef30ef747d5233e5f40e426d73cc4c7d12d086e9f48da9f83a SHA512: 204716b21da3155004b96e9a907322cec2a8c88d43ebf0aeda210d62d52bac8058c6fae062f0189a7fca48ebff687fde2725d619e90d4c907d614eed901e7652 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-remote-api Architecture: amd64 Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16149 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-remote-api_1.1.0_amd64.deb Size: 3437428 MD5sum: 6a4843641fd1c8db521967e991fe94c3 SHA1: f735a99fc966b09daee1d65e4f3ebf4f59839c69 SHA256: 0f3bf9c420f0b4113a0dbe266ec52efa46cb31afe22b4ef8090caf5a2d12a7bf SHA512: eebcc4dd820c888273544a901761ceff67ba04bd653d528f8af98415b3e13244595ef1053cd52d4f650e219c58b1e63f6352998c7233cf3ab9be9eb56c11c279 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: arm64 Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15154 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-remote-api_1.1.0_arm64.deb Size: 3136996 MD5sum: 47edfeca21f5bb1c90a846d5291c4278 SHA1: 8bac39957dd869be1b8c1a0d34d0e70cbe19c8e4 SHA256: cc331392e087d67c5fcf1cc8b1d9ad3eaa5d344e2adf25ad34581f502ad7fa52 SHA512: e845f39b9c50ce829fe85b73da147757d9b99ffb01eaa6afcd60a2ec8dcd1af92421bad28b6074ed4169def68d9a7d54f0773769ace8fc174c277859b2bc6694 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: armel Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14607 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-remote-api_1.1.0_armel.deb Size: 3103560 MD5sum: 168ad9020db1f5cc6dea7393a20c975e SHA1: 46511c11d223335787ce75e52ef3efb99871df28 SHA256: 492e93e3e9219ef94214efca784e317fdf60639d4374a10471398541f54d83da SHA512: 4f738e0afe4a0227d8826330d9b6b069dc428098844b7362ce8c5e8e59031314376ac5bde6674ca313b763670f4cbb7613865557cf25ecf74cb7933b160c95f0 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: armhf Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14484 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-remote-api_1.1.0_armhf.deb Size: 3139236 MD5sum: 1dee83da1c825c46b00cb4ad26e12559 SHA1: 62c3b552a2705829c1199dfcbe68a214efa34e40 SHA256: d14d1764a0a9a34156e83c5968c258d8f3beb1319539c7ad7c4b09e621514816 SHA512: c537d562dd0164729f452463450b2b7829a8977fedbc30b86adc3ded73313d34e13fecd0a7d5258ccc109c1f35740d5693687506312566f107454c082b01421b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- ## **Examples of usage** . Prerequisites: - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . . ------------------------------- ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: ```bash $ cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . . ### Example with a version built from sources: ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` Here, `zenohd` version is `v1.0.0-beta.2` where: - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. Install and use this same toolchain with the following command: . ```bash $ rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-rest Architecture: amd64 Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10884 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-rest_1.1.0_amd64.deb Size: 2098372 MD5sum: c7a16c2a7978c19cc2cce8573fcdcc7f SHA1: 675349e753726233ff52ac2d88f7f0be7114c2d0 SHA256: 4026c550b68c8570762cd413a8e25111c47fc3427ee148195856f02260130ac7 SHA512: a584a996cc18a8521d3668309e79e33bda36f997f0c3c28321d8831edeb3787da40e1d269c62879acfd2429619aba128d5f7bdfab4c27d6f8601a8e773c0a6fb 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) . . Package: zenoh-plugin-rest Architecture: arm64 Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9873 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-rest_1.1.0_arm64.deb Size: 1918860 MD5sum: 5c79322635f004540ec45d72b8ce7251 SHA1: 07dba4647053449cdb79f15ab711536ebb95c053 SHA256: ebdb5a8e8a2b57a185b677b415b765751249a33297ca17aba902379c2cc9e5c6 SHA512: acef76aff503a468e1678dabd683ba86054292fc99764efb860d300f01caa8a7784eea9348c28aae88724c951a0bb6808d59b8ba9d2355a9fa92da719033b0b1 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) . . Package: zenoh-plugin-rest Architecture: armel Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8018 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-rest_1.1.0_armel.deb Size: 1793180 MD5sum: 827c5103b025c1f99422faca71ba3eca SHA1: 9004cf65e6f1cf75b029dcc58c1847d84c4dd768 SHA256: c13b247432eed60e153631ce2cd791abef34a776fd98c29c30b40542f7a37aff SHA512: a337bc22b89d59cc9073b693cf6863de0fb359e681c9e6601b2046ab9a429a735b0a65988a1cdf521fdb1f0c363b75c7fc206e63dd2990dd1e523da5ff628ba9 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) . . Package: zenoh-plugin-rest Architecture: armhf Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7920 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-rest_1.1.0_armhf.deb Size: 1781876 MD5sum: 73eb7c4a8e464d55357eb8596f499a12 SHA1: 35f18c59aea17a92a2f0dfa3b69bf462f107fd31 SHA256: 6fec888a09df0191352372d4e2826ff1fd08321004732a3e8ba7157e38d6eff2 SHA512: 9884d60e2d6c173ca6f85b086fbd6fee86214ec393fb5a597a76ea47fb6d6ca0f45f96d14147655c5ec6166e5cf27c1d059dd2291e05ac05f9e77ab8def6be39 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) . . Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13441 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-ros2dds_1.1.0_amd64.deb Size: 2689864 MD5sum: 944d07a891e7cdd6de1af870855673c2 SHA1: 7243b5e0e32cd866c268b5fe0e1468cc5bf88f81 SHA256: 6c913cb5c140c7b2ff345f3e0c0d4e1da60a117f7d24d091042d3e75f9aaaca8 SHA512: 89e65039587c08ad13f0dcae5bcc059997c5f4d8d4d1a233c38e0ff097ee3368700cd00b9adb04823e3e040810decc791fc900c2d73562efba1502a0239d22d2 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 described 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/](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](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 maintaining 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12189 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-ros2dds_1.1.0_arm64.deb Size: 2450608 MD5sum: c812e0029b934c2a14cbcebfa92716ea SHA1: 9f7884e53f22e2cc0f17f64ed5f28ad2e4417365 SHA256: 08dfb0efc44c4571fe9866707f4af93b206e5fc8f11d0c9df3ccd9474dce55e5 SHA512: e83293d12b97cc21e36eb973639c0d3d623600d308b51717955efd4467ca6db106fa7b65c2621d15769809360af64ba9790f87c0feb2ea802484bc19358e5382 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 described 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/](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](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 maintaining 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10241 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-ros2dds_1.1.0_armel.deb Size: 2311896 MD5sum: aecb42085740d55bfde7c9a1e1bc1104 SHA1: c897afa2561ebf70b82d87df76ac34b7bd27b731 SHA256: 0321d3755a142f495d8315f0c39e3e79eafc23a7081cbe3d6ca52d52c7d0eab7 SHA512: 70fbb41e4665bc7080e7a95f1647db189c1cddaa69e7df627c1b797807549b437b24795c4a49b6eca1b3ef602aadc453743a0fb1de3d4db55d2cd996c3e776a8 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 described 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/](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](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 maintaining 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9859 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-ros2dds_1.1.0_armhf.deb Size: 2319792 MD5sum: 0ab62afeb9047f93b8d1a40e34510c07 SHA1: 5e65f40d6e14ba779720b81475ca23a7a6fa3fbc SHA256: 035b562a26c66c86e0c9ddea9691b2179a63c67804aff2d0b63722f929d67651 SHA512: 72c80eea5b10a481ed711a85f06fa74d768a8d878093a5e638225e259b19846ef5b19532bec0b01fd8c9b5b41b16c55297f18909833126323f5f6b52c0f911c9 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 described 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/](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](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 maintaining 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10621 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-storage-manager_1.1.0_amd64.deb Size: 1988228 MD5sum: fdee98525013cff464a3fc62d85a62f1 SHA1: fc1aa6336afe33542dc32199198c2e772b6d3725 SHA256: d900b5f80bfa660ea4e08a357dfc28f3ec051418997598d3917b988e3eeb56e7 SHA512: cb2ee3e8566e3e10c8d83134e81f639bb418c27a6d62a54aa3a51b045f27f15e73d2112f593b417e89e47909fedb21faef9f812cebcb34c2d99cf4c9a1e22595 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) . . Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9596 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-storage-manager_1.1.0_arm64.deb Size: 1812864 MD5sum: 63d08134cdbc6c998c475c0b76594846 SHA1: e1a9e7f0917da2dabe89e89f77707f41f649ec16 SHA256: 39584a139462c8f6a7173008aa2880f3cb2999d3a102fd64db8f6bcd730b3175 SHA512: 881beb3662a9f33391bd6b7fda850aba2be9e155e80834c1e211016d709ab78fb11a658cd19ca7cc2f0efe68cd1a0927dc79ab9c63df403b3d631337a62108fb 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) . . Package: zenoh-plugin-storage-manager Architecture: armel Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7775 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-storage-manager_1.1.0_armel.deb Size: 1706444 MD5sum: fd45fd4e76fab2489011112625e00fbb SHA1: 31ca776089a9b02d4c6c878089239483ba8dab85 SHA256: dbcd11da8cde38b823af2edb75b2117ffba211e1707c3474ee6d21f9b5e59384 SHA512: 28d66047a572b4587ef871cbd779dc8e6c01e5a36ca7621e2144540707c31b5d2c98a91734c3176db7a9c0f715e3cef756c5e22feb1a421628ec5cce0a86681a 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) . . Package: zenoh-plugin-storage-manager Architecture: armhf Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7661 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-storage-manager_1.1.0_armhf.deb Size: 1693152 MD5sum: adcb354bd8c8dfb0c930a38164a9a0a3 SHA1: b637d4c4a9948d6cf6bbbb126069889b3e0af3b9 SHA256: a0fdd6391f9df591b026bc9c32bfbb0e98cf188261e5c531b09d19e972507be6 SHA512: 1482689aeb676adecc54264ba4385f606fce7e996936340ad8ade76f15a317e2703a15cb37d0a341739c03c5798f8de9dde3805ebaa24bf7d9ad8c79afae56db 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) . . Package: zenoh-plugin-webserver Architecture: amd64 Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13340 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-webserver_1.1.0_amd64.deb Size: 2529000 MD5sum: 7f4cdb5aef7f76a42e3133ba5c812646 SHA1: 50ddb387387d5a84b3733a140b72646b19127fe5 SHA256: 5d053830db26667d829c4b0b897b777e94eb57a09bef364689607a465fb8c640 SHA512: 56704f65f0c96eb3dc9038f3a2eb93909fd9c53b8b6278c502aa9a3f201c19d071069738d2cf36e2662018b4edda27744da69a605021c0b32768fa7b841c8642 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12519 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-webserver_1.1.0_arm64.deb Size: 2358280 MD5sum: 4e20dea04aa1268bdcbcdb96c1468a12 SHA1: e28acebad49ea31182b055fa179b5185c2eebfd6 SHA256: c91df04eca5b567ab7c8017c903662440991cdd3be56e705eed3ddb653fa61eb SHA512: fe75aa9abcd1aa6da055b54fc4abe3a7b7da29aa1da43e74a4b4a909fcd67937b5bae4436c063c22429c0c0fd4c8e96272758a1a1abefb1fdd88adecded492e1 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10249 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-webserver_1.1.0_armel.deb Size: 2155768 MD5sum: 3cafd4ecad3f8a20c6ab86c0ddea3556 SHA1: 368b257bdb4c0ce9d56c4f1d90a9c5b9e30d17e5 SHA256: dfc48cdec76cc3632f762875806b9ee54e30999df1180fc40c5b6d7d677054ef SHA512: 6de74df381cada86462cc4d7ee1c089223ef0775c6db2538cc2a120db6fd7fd4328134788c81d6b51355bb19637a19591c7672b5ab07380c00a8aa53a089e672 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10118 Depends: zenohd (=1.1.0) Filename: ./1.1.0/zenoh-plugin-webserver_1.1.0_armhf.deb Size: 2141400 MD5sum: 4f58151787197131c2018145ede1b028 SHA1: b7b375793ecc6f1af44ad6cb90c84d75f3f29b7c SHA256: 5a560a85167a3d1df7f0425452d7d1403297866e1842282f5e37e7aa6dd53594 SHA512: 646bcf32c949f1eeb32b1562689b92885e3a9bc605329deb0b2933eb6d273a4ec3285549b1cdfe5db6c5cf9dce2958f5699b7da9c5ebe62471f1e12885380b72 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: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.1.0), zenoh-plugin-storage-manager (=1.1.0), zenohd (=1.1.0) Filename: ./1.1.0/zenoh_1.1.0_amd64.deb Size: 17460 MD5sum: 3ab7426caf062899fdf1e7974d56b25a SHA1: 1b28b0567a44d2a942c3bd300b5dc25d596ff162 SHA256: a30e4e4442dccbdd652ffc1221e5183370d8733cdec7d5d7d6e4015e21a9fb2a SHA512: 322ca05e3985ea3ed3efcb619130025fbc66fe7822c9e5bad98e90b5b8cff3ab9f80447db8ac3098b6996954f4116b5b6907ef9219892c53d25707c42a76f5a8 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: arm64 Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.1.0), zenoh-plugin-storage-manager (=1.1.0), zenohd (=1.1.0) Filename: ./1.1.0/zenoh_1.1.0_arm64.deb Size: 17460 MD5sum: 93d95ead963dfa4dba1fab055906cb5f SHA1: 45b4d7ac0c3a9853e572f382a8f5976c3bab8098 SHA256: 7bb68bcd0524b245a5cfa306653cb54766436bddf9c71fa99d8c523c20d51759 SHA512: 23063bd7cf488f0aa076ff67a5ba64eae2b9e4b6d3a7c417e016854253b961658014da4eff0387a51a88e5385bc12ff406df6136790d38a141e7d78df0ce05b7 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armel Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.1.0), zenoh-plugin-storage-manager (=1.1.0), zenohd (=1.1.0) Filename: ./1.1.0/zenoh_1.1.0_armel.deb Size: 17460 MD5sum: 449c2d3c3849f96b4778f4d1a397022e SHA1: 4375989e675de028bcbca209741ed91259157527 SHA256: d95daec8c3998fda3d7d0032be8ae79f580f06355c173a8a0c93b9dfc7c60c6f SHA512: c512737b466770fe2c8fdfef84cc048b5b1b52e6b0e427f09d0fe6d80f795336dd856e5b5ff785cd4dfcd70cdd518239257640df29e8d32abffbacc5180562a4 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armhf Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.1.0), zenoh-plugin-storage-manager (=1.1.0), zenohd (=1.1.0) Filename: ./1.1.0/zenoh_1.1.0_armhf.deb Size: 17460 MD5sum: c1801599769faea09fcdaaeb8d8972bf SHA1: 43f395b3b59f986e8c5b059bb1b56c10f2cbdfec SHA256: e567833b084a21fd2671b0808cc805508efcb2a5d95728aac211a8e674cfb815 SHA512: 867337ddf816f6d47c30018581bcb1c78a776cfafe495137a398bbdade218d7d13e5c76f24759480352b5514abfeab53aae1f0aac328d3e28700e2ee8c4d2bbb Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: amd64 Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18430 Depends: libc6 (>= 2.29) Filename: ./1.1.0/zenohd_1.1.0_amd64.deb Size: 4505972 MD5sum: 4a3c5b1927598427683d223eff98b339 SHA1: 89bfef6bfe7d10013115f547e1f1ca08a3d6ab17 SHA256: 6cf4d10a4b46057079bab8fc8c51f30afc7af1d72e73d79de9ee68861f1e6f56 SHA512: e5cd6f7583af6740188428b8cf0c1b3d82c14da634cbe7dcda1caedb1233e5e30e90bb50e3244800e0546fae88647fd75a9b7b9448f4c5e85f0d27a1e2ea84a0 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: arm64 Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16551 Depends: Filename: ./1.1.0/zenohd_1.1.0_arm64.deb Size: 4051688 MD5sum: 6572de0083731fbbe35bf5f7e5ef370f SHA1: 22ad17c871b74d3137577443adb3ed85f3ac0355 SHA256: 81fc11f536ef3b931e75609a79b946313670b5af6db785489412a08acd1774c1 SHA512: d6ae9b7e63fee230627ba898882c356b0cedd28a491628eb9aae06d97b5006837105f64e5e48e1758977a98371e6f6eab351f612a95b57556c52be8da98ce7d8 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armel Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17945 Depends: Filename: ./1.1.0/zenohd_1.1.0_armel.deb Size: 4409612 MD5sum: 6624ab993c641b5630ade34c94d29d48 SHA1: bef37f88323309a850bcecf2abfb22d6d84c6f11 SHA256: 465e012e19dabee24aae8083b9b266e0349d72a278faea6bb29c16f465b3287c SHA512: 7bb35dddee26e2ffc2113332b6777db10a555655624c7521a3b7bf0ec201f762f55ef0ddcdf875377b5b5005f90550de4d7491ceac80f14d16ae69082645e3d4 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armhf Version: 1.1.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17724 Depends: Filename: ./1.1.0/zenohd_1.1.0_armhf.deb Size: 4466276 MD5sum: 6928ae001e30bdb58a57b890fce96f9d SHA1: c2aa84385e93f2651e774fa360b499ef13a2346a SHA256: a6106b9429ff8d4c2a23898176ff69dd55166327c18e6893c38b26d8518db394 SHA512: 4a43292dcc068b16c853c37d3809bb450d91bc2032e87f163716855095e3a95c6e66584705dd4cb4895c058b544d336dfb81acc7d439381a8e3c2024df71bedc Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: libzenohc-armv7-dev Architecture: armhf Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31039 Depends: libzenohc-armv7 (=1.1.1) Filename: ./1.1.1/libzenohc-armv7-dev_1.1.1_armhf.deb Size: 9541752 MD5sum: 4349da37bd5c532c94ecdbdbb2c14da9 SHA1: c83b6e4476efee518a6971776ca83612700afad2 SHA256: b24b1cccd448e14688d6c520401ce425de37643c4a970822907ffbeea628e403 SHA512: 495aca6374bc0ee7104cf52f09b85b832c22113f1b253587acb8b9ea24776c6ef05bc7bf5d161ecb436c05154083813070c431a4fd68f74596036e67001a4b87 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18436 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohc-armv7_1.1.1_armhf.deb Size: 7039342 MD5sum: def1af6e9c50a885b72c6e506f51868f SHA1: 0328b4c68caf103f1577018b1c81a8713443990d SHA256: 93ec23b60f29340e3b84c889b21f1f1fdbf254acb78bcfff6dfa03ef6a494e36 SHA512: bf8777815adaf17a3ba309671532fa4cd2935298593eac750940f88cb65e035c7c400424917c16500095af36e663f97c6a696246fd8f552c0d51f05c14127753 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 39167 Depends: libzenohc (=1.1.1) Filename: ./1.1.1/libzenohc-dev_1.1.1_amd64.deb Size: 9109330 MD5sum: 46d6d58c9bde954289961ec07390adbb SHA1: 94ec60d0d3d7379f3189f21efd7004816ca3d6c9 SHA256: 9666fb741f78e833dd53f476d07d2ddeabfbf7fa785e9c09908cef82585a11fb SHA512: bf8af3e19e34113dd752c3df4f77428544162acda18f8592930a2386acb59108c34e2955cb291973cb8d873b84618f15a77fddb2a1464ae8d473d94fcee2453f Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 39522 Depends: libzenohc (=1.1.1) Filename: ./1.1.1/libzenohc-dev_1.1.1_arm64.deb Size: 9195312 MD5sum: 3eedd9858a568cb18cbe87278506271b SHA1: 8e3f8d03d5168ffd4380fb5a9f52f02bfdafa874 SHA256: f302de9cbbc505da81bc84b279f51830c25789ebc27b5f466548ec1adf461729 SHA512: 084c32fa86f8b3009d87d20710230f947822db6e5e0259b2b59164510f940e54130d812e958e321df9e427599b17ac5eefd6429531e6366c92d6aa4347600773 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31890 Depends: libzenohc (=1.1.1) Filename: ./1.1.1/libzenohc-dev_1.1.1_armel.deb Size: 9734398 MD5sum: 3a266c925699875297cacae02b2a6916 SHA1: 21999edcf73dad081d4bd5909ff58c619de840bd SHA256: 27951a18c8390e2d4c3eae3f2ba317a178394f6408d54714d4974fe9535c21ea SHA512: 0158540f3921aa4b3ef6dff410f93f7cff3b7f8be0ec984a350ab701c6af343f0ebe24c3cea2adcc6a99d606b7d3e2724c4eb0774464fe562a6ae24d6bcd5a4e Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 32055 Depends: libzenohc (=1.1.1) Filename: ./1.1.1/libzenohc-dev_1.1.1_armhf.deb Size: 9838834 MD5sum: f1811ce5a59f5015afa6a6d86c26b5f9 SHA1: 37f83d1c889c7f8caaf454e54cbf22f47da0df90 SHA256: c2e5d634cd1cf659cd22e47fac7166bf1c1cb43abb9c89368bbb1eb5c966caad SHA512: 82254a6c5e9413f733f02d194f10b14d305454f888b95e933042259e8d1fcf0186f3e0b7c1a8969507a1a14aaba732db6255d5b8e91e366cd7b069d8aaa694fc Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 35040 Depends: libzenohc-musl (=1.1.1) Filename: ./1.1.1/libzenohc-musl-dev_1.1.1_amd64.deb Size: 8864764 MD5sum: 5c3b528379725f3572695545b2e540b9 SHA1: c6e07d4b0acb13c40960315069f987e14369e18f SHA256: c06f6e7dda7b1ef731f24e7c5c504b13f8c7b25101a0badbf97c1acf10596dc4 SHA512: 266a7b36a0dee5491b78153cd1585412fb50acf34053cbee0d40daeb126ed7786f652afd115431bc6b5cb3a76d2c606062569e3d7cb963254e4b905bf2b2eb4d Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37515 Depends: libzenohc-musl (=1.1.1) Filename: ./1.1.1/libzenohc-musl-dev_1.1.1_arm64.deb Size: 8942538 MD5sum: fafa5328598ff6d1774bd979890961ae SHA1: c3ff322b8afa2e278dca4a98d255bcc3f8a4954c SHA256: 038747d454c3b28fcd424ca700b6c3fb6d81eab83ea64d4498655c50d6ebbed9 SHA512: 3174094de7beb3ba86688e12c3454b0cc109d6f917e0ede2c798f952ff6ce2fbc9acd9c7657bb0d3945a5df833b99b892540fe056e3f17ed242fc81f37a22ba6 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18543 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohc-musl_1.1.1_amd64.deb Size: 6726322 MD5sum: 378baa335dbb6a6d5240fd228162e5d8 SHA1: 982c9c91a68eec85f6824c5bb33414f54d9b9550 SHA256: 5851e413d82345f89f8b8268494511966a896866892caed8c5b5dab916e124eb SHA512: 43906a73de19a9c07d0e4573f709dc43e95cd9af38ba45192eb0533ae51d56bc731b2c1fb316900bfa2d9f9d27e7a26ca25567d92b8a4127507abdbff17751b5 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17208 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohc-musl_1.1.1_arm64.deb Size: 6410506 MD5sum: 703a979baca2354d48fd2c6ee2637ffb SHA1: 523e3287e8be24dc37285e2bd8570198a303ede2 SHA256: 30d93a0222e401bb189a6b8ffd066f181d6f442f29bafb99b207e03b946c1eb1 SHA512: f4ef0b791f2797af7e9884f46a67c4381128945a220ce4c9dd8c9cb944c76bd7740d5ef572e0a0267a840716be2138adc67039aca562ad33fb739fe8a2999a86 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 19126 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohc_1.1.1_amd64.deb Size: 6747126 MD5sum: b39cd7706a2bee37bf49c91406cc58e2 SHA1: 21248ec92f0be5dbe98ceb59ee639275dbfce138 SHA256: a407e002c42d3dd82e27fb3ef5628621592377a4411718c6db4b03690e445054 SHA512: 6702f27315b3bdbb61c0e227b1778119f9f13e8c19cf909912ed05b9fc5da80676063ddd8e3df1b5fde44199c3d17ac7c35c7f009a4793eefddd77bd2ac8847f Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17549 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohc_1.1.1_arm64.deb Size: 6469372 MD5sum: 3665f392951062822b099146548b0455 SHA1: 475469a285b0d0fe3c50d5d242399524321efaaa SHA256: c80e9ad2846ee2bea343b64986260790d9cde57017cb818e215cdd4c92b1ccce SHA512: 8d4864e0522350824ce2ae5fe353989fcf619674ffce3281792d56407ee655f06b35b233d6b4cd48441b41dafc82b8124a3e551171611d688a043971783cc722 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18841 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohc_1.1.1_armel.deb Size: 7124464 MD5sum: 8d97a182d8336915cd973b107d32f6a6 SHA1: 91645fc58627ed963bf482afce5e5091776ca00e SHA256: 854c4b1a42e9c62677426429ab6c61589777870a55b310d8f13df86e83537e6b SHA512: 91513e0513aa6a2b303286716aa76f18088d6230d08b88dde4814d7e907b67df01584ea8a3180ea5d61d2511b070cc01b5bd3b89972846deb058a9a186cee707 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18829 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohc_1.1.1_armhf.deb Size: 7196436 MD5sum: 4c957d040e7f786f6115a8f65e839145 SHA1: 789417b9c2bd96f42f41db3d08ab5e97b34240ac SHA256: 57c6baac681f5223195c583d017b857f18118eac391d747a3f7004a2b5759748 SHA512: 0247912b07fe5d2cd1f0caa50cb935121dc6ee304841a6cc1313edd499444dafeba13673f8e87633e2ab5c3e198da30d83e281dc1fc6de0bc6f99db2c49a2b31 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 442 Filename: ./1.1.1/libzenohcpp-dev_1.1.1_all.deb Size: 56634 MD5sum: 333b44857247014f09e88ccbaca5e47e SHA1: 9f965574d5ba3912e014dc47e76ab4e2bb9f0321 SHA256: f2f6f17ff848e97ec4da70fc969f59a83937071b5ed1b113fa9cbd41ed01a4d3 SHA512: 9fb5258dd0b5c50e7e0d82d2f178c19d7f6006a831a54aaad69f0999108f362f2ee3cf99f45aa83dd0331ab265c851c02a7b71697c2a227fb00cead0dab16f8c Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1173 Depends: libzenohpico-armv6 (=1.1.1) Filename: ./1.1.1/libzenohpico-armv6-dev_1.1.1_arm.deb Size: 236314 MD5sum: 11d6ee712a808091e5c188b3e5dd8ca9 SHA1: f58cc7fca36011dfa79fb739876b212a4385de97 SHA256: 2b5416028b4666af2370cd46c1c60919de8dacd5b3f545302fc2ed0fa235b13d SHA512: 3929beee690d0ae67b8a020cc60863fde2d8bbfafcfa6463e20e5149ab1f2b90821fb24c01635e97ebbbf0040193c0bc91aa1e751c6f90863133fcc929464d7d Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 344 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohpico-armv6_1.1.1_arm.deb Size: 141228 MD5sum: b2b8cb3d49c0e8231b229764174896b9 SHA1: 0ef7b0f1ea6d517b6b6348ea8cf11d4bf7ce8603 SHA256: 145cd6ab1e63611dadc7c924670e6c97a59c620b35933e962bf7fa24c2123988 SHA512: e03bd529d28b762146af1dfa41158a733e1f3e35cf904eaf92bc06e4c0b2ea032b21cc413dee1e5a9c0a52b8ab476ef84d6e19cf95a8c9addabee1b8fa9137f0 Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1166 Depends: libzenohpico-armv7a (=1.1.1) Filename: ./1.1.1/libzenohpico-armv7a-dev_1.1.1_armhf.deb Size: 234842 MD5sum: a817392f1bd58b43f673ca2d5231f7b0 SHA1: 30b7ca7ef3cdcb51b3f0870cf06de63cad5653de SHA256: 1449fc0a44fc76de88a7e5d0e54b72f87adb8e457e9897b06892bf7cb718ad48 SHA512: 2db72064b5ea80944d8370cae3fe1fae816986d0e38d656db9d59af6a6b3cd1813c9246f8015fbd5c5950c899ff32f7b1f6f64038f93d8933d006bb1d4ba310e Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 343 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohpico-armv7a_1.1.1_armhf.deb Size: 140682 MD5sum: 4ed5d52b4888803570fee720a7a5def8 SHA1: be5ca649fa4d42e42fc2acf92ecd997a7d5b08be SHA256: 763df626dbb13299f4c7233fd2c2fcb980431f07b20a287d9a085cb79e46b288 SHA512: 38efd83fe87c18b5d3470d2a983b10c49d7f4775465bfabe7813b33812ea7098ab0654cda8548c7f9343255ea0f7b45b5459d7c5f8964e4202c052f550740ce1 Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1413 Depends: libzenohpico (=1.1.1) Filename: ./1.1.1/libzenohpico-dev_1.1.1_amd64.deb Size: 281356 MD5sum: 0a811dd787db0708520ab46e81ec956c SHA1: 7c866cb110bf4beafa9df6c368d852fa9d5ef1c9 SHA256: 088a1398d982fdb4575620b0245dfe668e0f5aee489067e5b319ede13074ea32 SHA512: 8e8ef172e4c1dbb722ee85bfd4624cabc8d5c77dd4116fcd6ad0091d8e9aa911956d0f7f8f3ec66996e181374b858a289d9ca016eafeb11e2d1981d66a661742 Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1172 Depends: libzenohpico (=1.1.1) Filename: ./1.1.1/libzenohpico-dev_1.1.1_arm.deb Size: 235996 MD5sum: 61b33c2a3e88e5f7347871dd729e396b SHA1: 6ca25fb466f5c399f04673b8f010ab374fe9d043 SHA256: 1077c045c9ee0a6fc153cf0ee509fb0c017690c4d57414ef0df1f0c4543fe63b SHA512: 10e24d336495f0f655de4d42de414d475df5e28ea6102ec532e51cbbe1303f047da0b836d1defa3cb717af92c84b6a0839c107faad753579629ea02ced6250a7 Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1424 Depends: libzenohpico (=1.1.1) Filename: ./1.1.1/libzenohpico-dev_1.1.1_arm64.deb Size: 278042 MD5sum: 8c9d81d755747e102683f17297e92fdb SHA1: 1d4e19fe0dbcbb24975534b4b9dfa2af2bd28cf9 SHA256: fc266fb136989fa7e73e84b7f4e36ce08e6e27c8f6089e3f591a5108a9fdc736 SHA512: ed3cbd2c732852572a0650bc903d3374cd177267250943e757c60b6e1f94103d924d247271e799e707bac3b913960fa281c615cd1891655613e258c2e572f6e6 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1167 Depends: libzenohpico (=1.1.1) Filename: ./1.1.1/libzenohpico-dev_1.1.1_armhf.deb Size: 234608 MD5sum: 7f85e777e4981add60dcd7db61837f28 SHA1: b8ef2fd9ed3ca9048fb20a388484f72c853daa6f SHA256: 512fec8de60b565312600f47f834497eefa0c03f4099601e719c10a6f681ac6e SHA512: b719fde91a2be1c9fc500209efbf5be26563cfb55a4d5a7f4c52450e36f79a92b148291df26cc3ce48c7c222b99a0e244e3df71e827ab49d4d7bc1410e21783f Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1385 Depends: libzenohpico (=1.1.1) Filename: ./1.1.1/libzenohpico-dev_1.1.1_i386.deb Size: 306154 MD5sum: 3fa3f9acf78be58c9ea3cafcb4be7b53 SHA1: 2fd8d35ac14ea702b66a6ecd20b37b903b6a7aba SHA256: 03289231c9f7dc2357a1400aa0d2e8b365aadf0a777bcade0fd172934eea77f4 SHA512: ce7e96870bf182db3767a0dcbea6d2306c81e657cd98babdfbdae4394befff53ed0d13d948dcb35fcab954032bd862903e412d263250c182cb96b2697b868cac Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1314 Depends: libzenohpico (=1.1.1) Filename: ./1.1.1/libzenohpico-dev_1.1.1_mips.deb Size: 266362 MD5sum: e5b727a4b240f618e4fca7a56cc91b83 SHA1: 1a0bfaf7acacc2ddf602ae44394e3972b5f1e23e SHA256: d14317acfd66310d33d1a4adac0830d45169d6254755381b63c59a8f615e8e17 SHA512: 7a22f3332ca0ea7f10d797070afb8b854a5c034ce9fd56e8f598bc8c1fa6fbe98d8d8bebeee723cb2ee6fad8050f081b1ffd60833ebfd93f3374cc0876e7a941 Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 463 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohpico_1.1.1_amd64.deb Size: 172152 MD5sum: 0160a6709aab6214d9094e41cc6a6039 SHA1: e91ae713f75aefd1beca6f8b5291bacf402adb58 SHA256: 03db3f0080698c3677f804f2216e7881b8768389f4a13f56850d50f4179b58c0 SHA512: 966d07a26c7767acf64dd79b3f45258a62bb8b19c09f3e520dc5920a611c37a8f06ec163aaa16b64644281ab1678e3251b4e56813c0dcecac78046a0a4e5e3b2 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 371 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohpico_1.1.1_arm.deb Size: 149630 MD5sum: 658f6c3ddda1a19a1d0d3c081fa3eb08 SHA1: 29a0125a8f99590f5ccd73c7cafe22e83d209254 SHA256: d6fa33e0c779568146fecb2c56b3dcf46f04cba2651f90499db2652900465e5e SHA512: 60ab0e2d377646cad1223e71a65a18a1e4020c2bf148c19b77c6561438c7a8b927d5e5c1ec56da6dad275f05cfcc8cc48f3d06e91ede8490a295511a08f77466 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 481 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohpico_1.1.1_arm64.deb Size: 170012 MD5sum: 2b465a468bc28b3205a45c0b2f0a1661 SHA1: 5638cc47622959537041258e6a881937293fc4ae SHA256: 6c9a25b73b512b84c7f4520444f9e9fb8e85c908d13321f11a78aa31368cfad8 SHA512: 11bd4362aa435f462111af8fd3d0901f4b0e22596fce8b8d2f1e1b62dc0ce9646d0129ea909259944160496c51b4cf667754dea07a6fbca2f93d0c21b55b21b3 Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 346 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohpico_1.1.1_armhf.deb Size: 141808 MD5sum: b222dd5822a86bed776d50084c721196 SHA1: 476bbdf67327ffd5502ef7c7bbe8db9e4897f26e SHA256: 1c934f628520bfffd3f553eb999495f53f68b966c797d60bd6533b29ee152295 SHA512: aa3abd9345772310cd270eac22c48ca6176fd7d4041885b1ad6d8724f5b983d8a66ff3d65eca7afc51c4ffd733fd856936e789c6008bd6580c2be28bb515c6d3 Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 489 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohpico_1.1.1_i386.deb Size: 195366 MD5sum: cb102a8095a1f2d9b01ab236073a5efe SHA1: 4f8c3c1553b37e2357893f04e6f22e83efc85ba4 SHA256: e4fdabfdc9941b0b5d296b6ab9d85002693858734c20b8308c2034ea1fd5f321 SHA512: e535c3f585d10991c59512ab0b2edaa17f3fd8c3c10f8138a997798bcf96b343465664c4361c476427c305095fa0c53760eeab7d83feff66d4825637174ebd80 Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.1.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 447 Depends: libc6 (>=2.12) Filename: ./1.1.1/libzenohpico_1.1.1_mips.deb Size: 154414 MD5sum: c6face122ecde372bbce1bff7e4b5937 SHA1: f619353bc857e543c32a513e9493f51573f509bf SHA256: ad336e3299f6a33dabd7069159b952c2453ae7bdb285278a22fc21ef185f190c SHA512: a713a590a00fcb3d63878a2d6975c236cc01d3f2653be4a180688e9f89379e4f5a83aae675663cc2f859cb0b0c37cf82c1aaff715eafddb719082f94fbfee56a Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20836 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-filesystem_1.1.1_amd64.deb Size: 4601876 MD5sum: 3d4798a622996e5f60508ceb9b73bd1e SHA1: e00f007ec07586aefc374ce00450d22495236caa SHA256: 53a9dbad756f711b2c004e0be14f1f164de1e084925c3a305d1121ef7ab3b9ce SHA512: a67765fa172cfca9f8fe2b22a9fed87e495c8cf853ea78cb3bf90c69f47dc1338307329668dae937bd4fc9a836a4600a5ad7ac46bc4649738361da8b29df8224 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18941 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-filesystem_1.1.1_arm64.deb Size: 4140792 MD5sum: e8fe98c64287a5dc897e7bb05548034c SHA1: 8e2d2bf3b6bfd3286602ba9c75df8798964c0b06 SHA256: ff6ccc3f30bc0684c04cd0320e6658e2999a064f71c90c262bd430b6bddb43c9 SHA512: a61d95bce871c81d7238dcdda13f3399791cc8058b168b2da0410404874693d574a45bf237c37b5daea0df137b60df28f5d5bf7e0daf0edcbb952ccec4e757af 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16517 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-filesystem_1.1.1_armel.deb Size: 3914168 MD5sum: e6768804c13f8f82ed779f990e37c18b SHA1: 37625352744d1b7d1c1ba7343724d891ac09c25d SHA256: 806de076f1660d0220783447d7e6ec758b0377045f711bf6f2b8eb1432f44e70 SHA512: 485744df14cfd4a347d92c9a6f1c482785cf17b53b2c3ab3bf61cd339d4daa62f2eabb75d75bc37b7cd309bd6fe020ffa3615e43d391134149687fb04f37020f 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14632 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-filesystem_1.1.1_armhf.deb Size: 4010284 MD5sum: 94aa3120b87c1f9d7be252bac69073b5 SHA1: 5c8e55482765c17616147f6a4642a39cbf0160e6 SHA256: 940ec5158bc7f7fd217cedf5723de6f787b14427ed559c394752a9d4b4d8437b SHA512: c2f4d6fd1d3bd908b1769ea18ac94381456208346941cda62e522ef2d2c589fbca5147176b3bd1552da78c6ce65028f36b45f84e2b78f9586ddfcb5f5bf40e61 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15712 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-influxdb-v1_1.1.1_amd64.deb Size: 3131612 MD5sum: 45cfbf6e05e0e941b83fec8028af297f SHA1: 13d7ebdf7ea11f4aaa9aabe45935dcab2a0c4afc SHA256: a482a6e78d88dfd341286d0f18dda5ecc31f6e44a8e92f96b0001adcead4c7a7 SHA512: ed31eafe9d15c510d8c1dccccab4b721662b6dda75e0911cebd744eb903ebc1fbc30ed4326b18699d3299d3b587b1e6e36994247f24c52cbc8475ae6ee017d69 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14049 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-influxdb-v1_1.1.1_arm64.deb Size: 2814712 MD5sum: f6823e92e5f417e4fb48e438f21cc3eb SHA1: cb6145abbfd6077b5f58258fe17fd0ab3ff146fa SHA256: 1636879e1a68b17eac992e7fe04bc1afe960c6a022559a829247153028a7d8f3 SHA512: 1c17a0db398592e612e2f4b513f4b3edc6a84acb979d626177f488770cd90e913147142e163b8a0aaded7573c5a92d2aa444918e44bf491a61740d32b95d187b 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11806 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-influxdb-v1_1.1.1_armel.deb Size: 2552064 MD5sum: 0d4a8f45bc2271e47d8ff0f023c6de3f SHA1: 250452155710cd3f551be113ff6b086a597dc182 SHA256: 59016a1e1d60a35e18fa898f42025aca7131c2d7ea5a8eb999b029249c1ccad9 SHA512: 6215f0c3929443b2d7c86ae9e9485c2893ac11c8b6d1d602e2f5dca796082f3e6262270ba40218c36911e38b69cefbab064c49e6ddf470f23a6a0b26653e2448 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11683 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-influxdb-v1_1.1.1_armhf.deb Size: 2544196 MD5sum: b4cb33cf17cb88f7f54ad04097530ff6 SHA1: 11693605a958aeda569100d6cf2f9ded69ff3a7d SHA256: c2b56ba86bd710bb7d04f2ac934af2780dd6740882a8660191d09f350ae075d1 SHA512: 5f6f5e073a5fbe46d6596041b829b2d21dd40091bfa053d7c455cb5adec935f980653424b8a224be9d1d65c1c2f5be3a687f1ef6917c76d4eb6e9add051f1274 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17314 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-influxdb-v2_1.1.1_amd64.deb Size: 3811528 MD5sum: 26fb7d0228b7437adefddadc8232ab27 SHA1: 29fc7874f2371891bad04edd97fa3dcb1c968a4c SHA256: fee996bb5ca9a35d230422c857363f89f992ef1f778fd766ab3a33673216bc2d SHA512: a6be466fb71e2eab40e70238d9aa188dfb9937c0b417e757e2e1efdc6780a647e06f95fb38236fa8e4a9ef26e64409acc0973dddad28b1580c515f343e5a31ca 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16301 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-influxdb-v2_1.1.1_arm64.deb Size: 3491808 MD5sum: 62e045a28a9c57abe2bc6ecc055d7cf7 SHA1: ccb8f7f6086e7799fa4446f3b4fc753fc08718ce SHA256: 460cd9e6970f1dba8f1318cd69fc3a7a818b56fd8b14067db25be55f26a5a176 SHA512: 206dff2fcd2fd29fd1f1789b0c4cd79718d44bd41d645eb8502cfe4a53ffbc34f136e1147e544221a1dc7cb0d6f511306bc84cb9cb737d782f28692cd3607fd9 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15589 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-influxdb-v2_1.1.1_armel.deb Size: 3469304 MD5sum: f84f04e80499b4be6953794d34af9578 SHA1: 55d69d097326af35f0c97c8f7c937a2437b7bd7c SHA256: dd3aa12b4ffd823026b2dddf9234ebd3a6a66afb034d94791f447726b20df068 SHA512: 24c6d84c6aff25d350d65e6d4ef9ccca027e4c5a96fc089662a5a4cb95881916ddd023428dc0b2cce35b87e99efd10c947a7144dba9b4daf2c53fa446ace8669 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15485 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-influxdb-v2_1.1.1_armhf.deb Size: 3513736 MD5sum: 09844a2e6e4be10db4ee71a199401024 SHA1: d32254a9e0452f4e03eb715e697f5c7044b8ff03 SHA256: 65c66b974560906503eee8e40a5ca0d19738bbd5887149471e624a2ca9c07001 SHA512: a00b6eb3f7ed57326c84c8fdc189a7e999e1a77763344513c74bfa864a0dc8970bcbf8f09730a3d7bd5915afd0fd1d76e15b0757f9e53e9e434b8b9f336fae74 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19387 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-rocksdb_1.1.1_amd64.deb Size: 4331124 MD5sum: 834ad9224222fccb1368b4208f142dd4 SHA1: 8bb14fdce0e31c3ae0da7ff37a367d0e0587578b SHA256: bfdb3327c9618b29467324abbac6252f453b2558de3bdeb5097e18af45beba0a SHA512: 89914570b3377d824ed969e2f30eed42a6a08bba74f9cdb8d31058ba24db8c858a2dc1b83a9f9cb506b05479bbb25c7c51e406a2b8f1626295d7dcafac8193de 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17503 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-rocksdb_1.1.1_arm64.deb Size: 3889700 MD5sum: 6228865383c9a80407f311643053289d SHA1: 199d13aa6ecb6e477fb3f4e22166e129eb097068 SHA256: 7cb9fa1e2d67a2d42088df6345dffa9b4aa6f761c942b2f8fe5514c80ff04561 SHA512: a8287eb061bce66086772e23ef58ccca20a83c67053641060b9fcbd9963b1d51e3d1d434c8b4f6535d7f1fd2501bd1ebac14266929fb549d97fd10c84d93857a 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15307 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-rocksdb_1.1.1_armel.deb Size: 3695300 MD5sum: 114576352c654d2a4327a8468eaefb29 SHA1: 510fd8b2e6595264ab77d763efab5895bf1eb154 SHA256: 72094c3331bdc00fd470e480a81d93a5b81b3a3f4126c525d995706e29c2562b SHA512: eef846e8a719156fb65d4cc69512052b1ca65208aa5ae16d138aedb57e513f954c2887e645252a3358eeb7a1e08333e95bc9448caffd010989f14322c40dc23d 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13400 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-rocksdb_1.1.1_armhf.deb Size: 3797268 MD5sum: 48b8c9b0eab21ad7962a7af7090a3bf2 SHA1: e309a36c072e1c7e185fd4253a051dcdd1bc634c SHA256: 6e60f487ff8765bfe75c630b03b6afd05a4a4b9e4eafb0c25a74172e5fdcfeac SHA512: c9c0580129c94cebd7403d07de9948d3cf07651e536763579cc298f7d7df75e31c70c476d1035e4b67e7e1bdeb2083fc7f8a3b7f80f82c865b50713bb0572959 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27335 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-s3_1.1.1_amd64.deb Size: 5518060 MD5sum: 89a0f4339f338411ab192327404f2cd5 SHA1: c7a73b0bfb98686f471d0e0b779854228b4e147c SHA256: 55754c277fa68b2455860a6b3e474ecdc6620df7b2c9751fc4416f67e09313ad SHA512: 9bba57db29d0d1f12ca063afa66860dd37ff4f8fcefe53e9c9d236fde6c13bd84f81c962ceb2ae5402bbe1eaae1c2e0451eab8a1da5ca20bfeeff77273719552 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26544 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-s3_1.1.1_arm64.deb Size: 5238608 MD5sum: 80566996cecfcb3badc622098924e647 SHA1: 3aeb921701b263e4e273164527b42186977903e4 SHA256: 010afe40cbee2b059f4104f7c91cfac26b5ec5078e2500bd59762be5af086415 SHA512: 57bdfe586a0fefdd8274a55392a2b95f03396e5af847ee3b75e15211ee916281fa865be576cabeb556921e660c08b25411321b6f5a47d2c4dde7e99d534d37b8 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25204 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-s3_1.1.1_armel.deb Size: 5093784 MD5sum: b8d3b1a8393e2f3a21c7089e4a44d5fc SHA1: c086a1a568e746bd919e98343fd7b9eb420f4429 SHA256: 200139b7d0d88d083a799496bc39ddbef12bea0b513e1ca5332ed4b5d84882ed SHA512: 5e7463a0cfedde6d1d43a595ac4cc60e4cc3329e0307797caf3565c5aec624428f8220151697e727fef9d229bc87b8fca0f19524b01d1b08b5f0015bea93f089 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24978 Depends: zenoh-plugin-storage-manager (=1.1.1) Filename: ./1.1.1/zenoh-backend-s3_1.1.1_armhf.deb Size: 5144944 MD5sum: 9a86888ebe2d7a3bc106977d86ce06c5 SHA1: 65130dc48bc07897c5655e2f2270429395c6f699 SHA256: 92a828fa65fbc1eadf21e05aae2077d8d2d08e7fe7f7d6aa33a512f22bce70b8 SHA512: a1cc1424914588186f41ce31977d16ade6f90f4b67ad02d3a328bf84c763015f4731556663e8f4d99570a77046d1b09348c86ecf52977fe0196cba260885933b 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20939 Depends: libc6 (>= 2.29) Filename: ./1.1.1/zenoh-bridge-dds_1.1.1_amd64.deb Size: 5356560 MD5sum: dc521610061b5ff5961e181ddd0471d2 SHA1: cdbe1fed0db8f22bbe3f5df09c57803d520007b6 SHA256: e41b056d5f6d0c5efdcd3e1f4c0851b9d9e689138ef4b0553998ef6876512109 SHA512: 1fa737cc8dfe33694ca822dced226c70d359904b2043cc9e9dfd5679bcaf5aa21d4e7b41584ea95442ed84f9ce4e9f699ceb3b0803795d76dd7ec99faa850970 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19139 Depends: Filename: ./1.1.1/zenoh-bridge-dds_1.1.1_arm64.deb Size: 4835172 MD5sum: e18c1598fde2013a222102ea02236536 SHA1: 123c0ecb2f5310c08219b1fc21feda781fe0b42a SHA256: 37f05f5888f6939931e9b7db3c0a617c1efb06605dd19699e72cb8929d7af27f SHA512: 6b763ad6df2859cc385f22e33d15dbf1c05d4a49c76a9fa071a02fa2a641f952de61538e279287aa50ebed27457906cbb9510f05dd5e5ed28a5a43ecb81c6d97 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20374 Depends: Filename: ./1.1.1/zenoh-bridge-dds_1.1.1_armel.deb Size: 5131036 MD5sum: 4777deff15d94b1f3a354ea5716cc283 SHA1: 94db44ec9a58cfcae85142ff104b4b7f87f6c7f8 SHA256: bb14bb8e51e5187a76e95cff414ba4c28fa45eea95446c8de7602afd05c8f009 SHA512: 1944e653ad6ae685621fb02102168144e695a873a158f3c68da1a96ddee5c5230d2be6ec517ca99717d7d47bbd6eff6bbbb5ca4dfba8b3b49278095869cebe7e 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19844 Depends: Filename: ./1.1.1/zenoh-bridge-dds_1.1.1_armhf.deb Size: 5180768 MD5sum: 913c6f9f94dc32c9138ef07c9ab1bdb5 SHA1: 9d00c5e9c146248246168e8ec84832e87e4e48b8 SHA256: 3e53b0a589dc3863607fdb2ce3409f11138ca6bb55cf1f585650368d065974ce SHA512: 31d35548ad85d54a9f0da4640c157ca92e8abcc9ecaa20a7861741124d4ee5ad76a9d6ccabb318ca57af1e1fec9cd2e295e197eca172731cc62d93f1f1468cda 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21309 Depends: libc6 (>= 2.29) Filename: ./1.1.1/zenoh-bridge-mqtt_1.1.1_amd64.deb Size: 5050444 MD5sum: ce64179ec43a729a82a02724ef956d67 SHA1: e28fb2134865128bce0001850ef8fb27bd33c902 SHA256: 3dcc38df99e95d6307f2c9118c4189bab2c08c2b25a43e6d071a3a5fb3034154 SHA512: 77e947e754b14de4fe7a490cb40e86cc0587ec3b90f6ff5ff21b7cb4ee109ca517a3e1191cc9033c30fa73ee3c2d73421ff648733523ad6b29ba1647f932c75f 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19512 Depends: Filename: ./1.1.1/zenoh-bridge-mqtt_1.1.1_arm64.deb Size: 4563308 MD5sum: c6613b82a1f8d889eb9355e0d44c69c0 SHA1: 798e839625214e21f15813531fc99c7ec14a0f61 SHA256: bfd802666bcc2356aa505950339ef3aa177f140914f55850c98705150642ad97 SHA512: 4f7d167b79034630b8cf4b1f026c9ee7db2cf2c1a5b0ae7784f26a8dc72b233baf1bb43dfae3ccd59697f54468ccf7a84ef17470d11e76ccf1014b4f8c4d1058 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20767 Depends: Filename: ./1.1.1/zenoh-bridge-mqtt_1.1.1_armel.deb Size: 4866316 MD5sum: e0018338ad8f34460fe62fffa3ce9db6 SHA1: cc4fdbfd67a15bcb12b1f51d70d198c1853d10e7 SHA256: c815823466dc9d036b972c9d4d9ce7aaa848e1748d947e043844865299563a22 SHA512: 9102b557743d418fe7236e35e283014d64d3a855d2fa2221351499ad36067b4711cfc9da8aba8728c02aa087f5c010f7b6b3e7d03b1c1492306a1383f8f71a55 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20475 Depends: Filename: ./1.1.1/zenoh-bridge-mqtt_1.1.1_armhf.deb Size: 4898832 MD5sum: 27ca376f03453a3848b34eb2821348f2 SHA1: dc1dc4bd758c41170650d50b73d166aaf9790a50 SHA256: 4fd679765a91dec40e4d9644b9819870ccb891d6862453732cd66364c2aea597 SHA512: fdfeba3a87b6ef132307bd53b0cdfef755e007ae932db3de882c8334a14147a20cf9f11ce8c244a4b321101f85bebb270a2cbe4d0931b43d870f61dc70593d2f 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-ros2dds Architecture: amd64 Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21552 Depends: libc6 (>= 2.29) Filename: ./1.1.1/zenoh-bridge-ros2dds_1.1.1_amd64.deb Size: 5469772 MD5sum: dd09e9cc6ccb41d7c60291d78f8c2826 SHA1: 7d3ea39a019832f33e997558458e66d8e27b516e SHA256: ad6481f861ad075149c6ee365468e0d6ce5bf89db972b6b86b9248a8e50794cd SHA512: 5cac7863df3ceb79e84f04c1207379f4c2087ca743a64c8f82b9744219f8a3fb8a0cfedd57423bc91a1a4d21c0b3487c93d2b7cd1141aed4ae0acb42558309d6 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19722 Depends: Filename: ./1.1.1/zenoh-bridge-ros2dds_1.1.1_arm64.deb Size: 4952456 MD5sum: fcb5f686564a1a1bb140784f42197faa SHA1: 39bf1c43bc363ea441290b5078ff57cfeb9c5ba7 SHA256: e755763738736b7af602338d2a901b0967082e6b08b84f7c9d8d155e02470325 SHA512: ddf22c0ec2d734d6a899830dc6fd243291c45ea0eafa4226fa65313ef1c79618adb4ec6b479aaee1167b58cffa51bdf0073d64c4c4b3bae16caa299af6809375 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20957 Depends: Filename: ./1.1.1/zenoh-bridge-ros2dds_1.1.1_armel.deb Size: 5249260 MD5sum: 9d0167f5a9e24ed7e742ff88382248b5 SHA1: 398b63c856f06710cd38a2b1804e982db62f7008 SHA256: 0e725d707217ac4d369c9917131337dc33de5e5fecfae68df1763f65a87cb578 SHA512: e35a526b559179a9686beb5ae785f2ccac45fa4c1934938af00fa33d209fe9dd751fedfdc19b137f331053b4dcb46a745caab6bbb7463fcf177add1e6561fba1 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20431 Depends: Filename: ./1.1.1/zenoh-bridge-ros2dds_1.1.1_armhf.deb Size: 5306232 MD5sum: 8e2d71851b71aa65abc5c09ae1c30671 SHA1: 96e8ed0c9e7615217ff5013b1280d800b6e8cf8d SHA256: 506f384f5e9cfed2bb586a9ad61f108f2b929e014126d33b9848e03be0971cb7 SHA512: 1ed3db082f8a497e5d972baf6557feb4e4f44414ce8c0adc8e8b8c0ec1080ba7fbbc6956d75e517b90bbe2485424c9db6ddd82d266cf9375870f74442926703f 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12785 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-dds_1.1.1_amd64.deb Size: 2582928 MD5sum: cbbb18fff0729e839d2a2eb2e9e2e49e SHA1: 7e1592f03acdb62ccfea3df472344053efc0c371 SHA256: bb1b44c489a4c63e55abf30e74363a75bc64ca96704d554b52800057a7078b1d SHA512: 925459c80f13f689f313af46b6f2a9c5444b5ad10ad41708c31fd6fee22ced999267a1f375c132a72bdf16c883a4a7289b4de849ac0a50ae7f04e88683fa348a 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11593 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-dds_1.1.1_arm64.deb Size: 2349032 MD5sum: c18efad9f4fcc42678d95c787f03062d SHA1: 2622c7499ef35bae660d4d552ceebdea1a6e6ace SHA256: 91b6c8fc4cdfa5ca9a91f9bff401ce4d8e6acb10d37f5dfb267f6d063a5a1086 SHA512: c19c42879732cbbccdd4ddff68fbfb8284af7051c8fab43f8acd8d1a6659d5667b324bf74a48d358c1d2a8c372476d64eeaaca87a600fb040042284b06356dfa 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9627 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-dds_1.1.1_armel.deb Size: 2199928 MD5sum: c93a128a1b5b985e7553cb3b67915c69 SHA1: 383c232e8cb96bbbf9cf3f225867998872efb99b SHA256: 88e2d00c0f6fba67916836a4d0d44be50f72f5345b0de0484e4be4a4c17e3ac0 SHA512: 2975625779802c12f5223eafd33bd7642f576f35a5ef1cdfd22ac56e0eb6522050ccad8baeb3a50ae6244fe2e8572cfc285ee822fcc51f03a31189829ba025b1 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9251 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-dds_1.1.1_armhf.deb Size: 2204244 MD5sum: 2f9e3df80a1be0b9c4207d7eb293c26b SHA1: 21a36facfa13079a678ec769c87a510c034851c8 SHA256: 6e6e6bb309aef90fbe6b33262e2064e71b8a8dfe7b3b6d4efb0408052c1290d1 SHA512: 4092e0b241c8cb5ce76226b14044fc98fa50727e971ddce10cbf34f49c6bf1bef10b9924242195b891aaf72272fe53272e6dffd3293763dc7a3342c3274b200a 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14114 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-mqtt_1.1.1_amd64.deb Size: 2892196 MD5sum: 7111d23d901ab02c030b666343876d29 SHA1: a9859863cd0eed9165e6ecfe9ff67a015268feea SHA256: ff5f8f086ceadcde4393f952b9468541e85d671d42e36a0760ff29376cad8e9a SHA512: a0542527cafbce9aeff7139f1ce2af2b0c28dc7d40229fe93508bf7168127f77c707f4c8162e8132722b4c1a0fe2cdf17d3a0079161e07216a986530e0d5e502 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: . ```raw 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12837 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-mqtt_1.1.1_arm64.deb Size: 2589424 MD5sum: 5d058f48c89eeb443b40a1292a4ba90d SHA1: 46053512190e2c4ce5e58bc1f214c11c482e582a SHA256: 884372b433405ba99c0ed75a629b9da963427c42c0ea91e081f76ddc89e0606a SHA512: 5fff121c14f9c89f35b6d3f1a7f8d4db06967951d3f08f6d49c2602047b1cf6ea634b98a4d4a85dbada2a490d2e174d97d4333a0bf5bc00970adfeb7f931e4d4 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: . ```raw 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12837 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-mqtt_1.1.1_armel.deb Size: 2655904 MD5sum: fafd14953c985fba85a1d8931cc7ef8d SHA1: e26a296ca89e80787010d274b3e9e4cd86c6a684 SHA256: a8d9acc019eaf732635ad54bce52c902ac246a780c3fa6b28a4e1d85b94f14b3 SHA512: 0632d9344010918d063a38c5926218244ccfa14948e9abe27c3a63bf28ae9044a682cc5ffc03374fe697974a0491019f39726e2ba903346d83c1eda820f5882a 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: . ```raw 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/](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](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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12753 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-mqtt_1.1.1_armhf.deb Size: 2698936 MD5sum: a82b8c887845e5225f7802f03129cc8d SHA1: 575571902c5d4115ae71b29c81b07c6048ca5cdb SHA256: 5c1860e6da23dc88ff70ba7bb761877ded00bf714c0a49a4222d42b1a0f43d10 SHA512: 52fc1294e9e18069b1651ecb01254f6f58b494ac3f2f9dc1274c51454daeaba04b0c2080a9e36896771ea53be691e1e5a5c6bf398948cc0b2b079119c72b0caa 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: . ```raw 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/](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](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-remote-api Architecture: amd64 Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16204 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-remote-api_1.1.1_amd64.deb Size: 3449412 MD5sum: 12dfe2ca4dfdf2f38e57e830f11b1224 SHA1: 66b662260efb5e1c3a5c6ad4e1a4a379ef5db935 SHA256: 4c2c1067706554852e2c5e97fc3ccddb738f30c5b9927a725778f3892b3ff0a0 SHA512: 260ea436fd653661d47dd53a760ea50f90c8c1947911a7ce10f1cfb904dd0600c728f226d77362ec375e9657573f972f429f6b812cc91f230d5a52d636b97295 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: arm64 Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15273 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-remote-api_1.1.1_arm64.deb Size: 3158048 MD5sum: d897b0cfc5d307dc6fff95d972a0e90d SHA1: 3b21844d354d911bdcb63b7602223c766d63fa0b SHA256: 4ca2eea1796b1b9de8b8070e8dee9feb2300132fb776cf48c9044acea85600fc SHA512: d54ff6a2723e15e2d1fa8da48f78b31279a09ca1f4504ad8e64d046aa74426ab5fcb72c46ca45686956e42551d56d637a8251333600b7cf62ee8d795cd4a129c Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: armel Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14719 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-remote-api_1.1.1_armel.deb Size: 3125168 MD5sum: af0c1abe7c7d4f71127859e62ee46c27 SHA1: 7473493d56ef10cf58025ff3d07ac90a91abd5d7 SHA256: d2118832cc688fbec8bf54c6f1a59eb532fd61b5e9e12829d7197f011b652031 SHA512: 3c7e71abe4f006bbea6ca2e1e360d233a699f86d09aef00b8cadaf983c52f4b40f9fb6d71911d15b3df8e45a6d6ea3f4e7adfb09b26ce5b7d4f45c6f4316d6e4 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-remote-api Architecture: armhf Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14598 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-remote-api_1.1.1_armhf.deb Size: 3159636 MD5sum: 7cd96bcb85c7a2a84e5ff1f6288b80e1 SHA1: e51e05ffcbbc00c462bc0c296734192686aee0d5 SHA256: deaff2683ab9fadcbf3d11b88325bf85dc1d4771638c76a3a3744f2a2ecedd7f SHA512: 757a1dde195113e405d329a6f5fa1aa367fde38c6a3a164471a62489dbea3e73d0fa5e891dd09d6814a12a3a82fea09f467491ebb71d0ae25da13a40ad64ae20 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Vcs-Browser: https://github.com/eclipse-zenoh/zenoh-ts Vcs-Git: https://github.com/eclipse-zenoh/zenoh-ts Package: zenoh-plugin-rest Architecture: amd64 Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10888 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-rest_1.1.1_amd64.deb Size: 2097392 MD5sum: 5bc97ac1a4c8a6bcbce33c76a4896dfd SHA1: 8f142c3f743fc7f4e3f3efddd99bc922fa8b844d SHA256: 402aeb7a0efe73dcc41f8fe361002d6ca3b7dec7b7716561d2cbb79d5f6f46c8 SHA512: 6e6a4a9db87b73558a65f64aed176322f0245f50d0ab322c570708a2fb3c53063c071a85f6a71ec5cdf1f20fd0d9f22554fe55ac60c8c2041a5002aab92b0fb6 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) Package: zenoh-plugin-rest Architecture: arm64 Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9882 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-rest_1.1.1_arm64.deb Size: 1921400 MD5sum: bd80d61d3d7b4490efa74848ff895aca SHA1: 4156c6be392dc835488377ca4c12d0959ab32c5c SHA256: 2d02c8568640734490011e95a919e13cc35d73e53e3793d47ac3f7ba500667eb SHA512: 8741c8cb4e1dda9adce8af470d39c0a236b7255285b7ab9f69d072b91ba1b01d966cd2734d39c487d1a549f4d570f18e8f0efd1b7e1b3d6be9cf1e29a7cc1803 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) Package: zenoh-plugin-rest Architecture: armel Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8024 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-rest_1.1.1_armel.deb Size: 1795096 MD5sum: 485e6f72ebd802d48779b0865ef7a991 SHA1: 7f64625cf6c7ffd3c7fd7d0754e64b0e59b55471 SHA256: 7a3fa5232aa78afacfaf0d13d6f892dca4ae632cc1af9994e2e39c5c034d4e3b SHA512: 8af792e9910b8833e18ff579b8f786b180cb1f65e58e0e741c2870986f86f20a80da779fb22cfce0d2e08b7b13c3840be8e807b97bee7cef8eaea587f29b864f 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) Package: zenoh-plugin-rest Architecture: armhf Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7930 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-rest_1.1.1_armhf.deb Size: 1784916 MD5sum: 39c49c6ee16d91487515f32c666401fb SHA1: 0d8a0dbb28876753ae6eefb01a14c1177ecf47b1 SHA256: af2cf274bebd8aeea801e361181175dc316bcb39a350d84554dd2bbece45ea50 SHA512: 6f843a2d9afa0d1469c0f24a4389c6536722bebd20d65e3622aacc7eb0e1035638a2d9a7cf9ce7aa177d7df09e4df2fdeba8c318c50c039ffa20fdac0c3e3900 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) Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13369 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-ros2dds_1.1.1_amd64.deb Size: 2683032 MD5sum: 7b29b9884adbdabb8860fb7854412d7a SHA1: b3f0aec10d82490e2c71d8c515465357195b8934 SHA256: 9d9b17620e81f806e7eea313d8e444d936140960d54a306eddcaad8ae0b140cd SHA512: 3c7674d573d12015eb56ffa6d21607a1901c5057ebee9b1cc9f50ec77eccffe11622f6f50c8ebd7620046570916c92913f62f64d58b76d348fb9a77347d422cc 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12161 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-ros2dds_1.1.1_arm64.deb Size: 2454124 MD5sum: f04bc7dfc58978378c510e591aa38c49 SHA1: 84498db4833636cf98592149b87cbf906deece29 SHA256: d481cb51570f409e756d1aab6691a8924587797645e4ae3cc2ea01b4003cc701 SHA512: f3294e4424f1cc7b8dd54193e7775c6fdb8b9d1a0bd6deb168cb484229d7da411cea02568038655fe5496cffe8e4549071359e1a9f1dfca8f5aa49c52665bf4a 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10189 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-ros2dds_1.1.1_armel.deb Size: 2308416 MD5sum: 6ecc6b4e831d6a7d3a279c5f39a3aaef SHA1: a1bc3317126db176e36143234b16434007abb651 SHA256: a30b609525927ef417aba507d47ec5c4755e08cce41c69ea2efd2d200c679c4c SHA512: 340d5429d31b4ac5ddf6151a40fc25f5c4e53db0699d5921d430dd254cf89822e56a0a769d805b1d7219a1c0f2f49a28b521afb9558f6021c8d62fa5ed5608cb 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9807 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-ros2dds_1.1.1_armhf.deb Size: 2318492 MD5sum: 814fd102ed77142d5687ac5a306b8049 SHA1: ece0e87a5e9dd33c8cddfe09ab24404bb9fe47ee SHA256: 876d73f6bf828cf970b1c3687337be95c1515dc9ed28991cac8009e5665fcc3b SHA512: 6fb3a72d4b3faa99abddfeaa7d7819419eca6d73c64fcaa10533fdff719dbbcd8cdf885a5976ec2bf4b7ed7ec9ad9df90a4c1c695c7ae0415fad8d5044f77ded 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic 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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10620 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-storage-manager_1.1.1_amd64.deb Size: 1989072 MD5sum: 2edb65bf17b4045ab17a3673953f51e5 SHA1: cc4162776142753c31871eff6773a77972de339c SHA256: 885167ea1ea78d80ecef8298ae6b5fff470cf83d6910fc15d3e5ce097ceb3edf SHA512: 5424f4d4874340c42bec6783637a75bdd3e2f696068924b747f4a047e24605b1e9240d18d4c92e8433ccdc57a20c043d7fc7995c61a7aa203a01f5bed828580a 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) Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9593 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-storage-manager_1.1.1_arm64.deb Size: 1815964 MD5sum: c259ba791b9385e83ab722d361422f22 SHA1: d13a4be442960b59a87a2a3b96174acc23dd15e8 SHA256: 1cbaa18566aef0a94bb43d155cc303b90530a4104473f1d13f8de1817697bc35 SHA512: 0cfbcf3e2095178e9c385af57287b15df1defd0bc7d828f0a8394e184f451a65b4957706db692cf413a2bcef532f889ae1604efbbc61e01d48ffaa4ac77e48c3 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) Package: zenoh-plugin-storage-manager Architecture: armel Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7785 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-storage-manager_1.1.1_armel.deb Size: 1709464 MD5sum: 90c457b5138801482e2278d8d5af6568 SHA1: beb6621c4c382dae92f44b5ecd0fa75e3570e93c SHA256: ebccb3973230912f5717c733be617ab6c27713322a2a2c10b0efe7f259cf88da SHA512: e51b739b311ef98b1d01981a9d1f62cb92febef5c5a0ca2a9d4fe5cf9be7c77ed6220a0217c8584edde4af3d5a5a8895e1283f5dcc0855f036cb597e2a5b4e95 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) Package: zenoh-plugin-storage-manager Architecture: armhf Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7671 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-storage-manager_1.1.1_armhf.deb Size: 1695792 MD5sum: c43089e8c557c6554469cf24130f95b0 SHA1: 1d3acf9b1c1e4a20d87701ae414d11d212f1eee8 SHA256: f4297ebeb585f7a680f67c4c8d21f2e9f7398106b4ccaf5b6262c05e2a425022 SHA512: c6416e1a43ecc3001bfdd4a02045014538fcad459470b27a3365617120ee80dcd8b69ed461b75dfee5cd3084a646733ac13f25f448bbec872dd7d214eb3f4524 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) Package: zenoh-plugin-webserver Architecture: amd64 Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13296 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-webserver_1.1.1_amd64.deb Size: 2519744 MD5sum: 32e6fee498f8a680d4cb8f8f67e9e6e5 SHA1: 3637bee96e36f010d0a0b4dbc820fb3da17ea6e4 SHA256: eed53e0f5d55fd14e751d0992ed3daa9b20630965e4160ea0c07561b92fe60cf SHA512: 2177a9e9ff07adaa79826a4e0bd4c6afa44fba1f1dae527b325c80c6cfd6349c40f25a811c60586dff7913d792836e79d6f9fe547e0b4ba2352650ab4306e871 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/](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](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: . ```raw [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: . ```raw [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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12510 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-webserver_1.1.1_arm64.deb Size: 2354468 MD5sum: 410a124070f07fae9d649f3400e3c497 SHA1: 717b7d7b3f0d802b9ce34d12b231c006c44be5e8 SHA256: 7eadf63e8c8171e42b165fc926652618de4f22b751d014289ffeeff9bf700ea7 SHA512: 6cea94227c518c228a82afef2de3bac3d6a5c4a72641641b21e8b89398cb5d5650f3570d2010f9abbbe511c17bd278ddaf7a8077d2fbe209d2a2dc8fca07fbb7 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/](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](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: . ```raw [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: . ```raw [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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10245 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-webserver_1.1.1_armel.deb Size: 2154720 MD5sum: 0ee63b3eace1deb40a34af82e75b6200 SHA1: 661239fd32e02e9fd1fca223e14fca41caecde3a SHA256: d4fa9d5f2be1177cae6e3eb6ebd0416621cb514445deeeba690376e2883f0a7c SHA512: a4e5d3747da87b59d0156561d046e9e1b3b4c93c41ba8c4c0f7cd4d6fd49815f3660df7b7b6704a50caeabede18f1cb966a17e4467f3aee8245e4b3fd6cdf854 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/](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](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: . ```raw [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: . ```raw [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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10113 Depends: zenohd (=1.1.1) Filename: ./1.1.1/zenoh-plugin-webserver_1.1.1_armhf.deb Size: 2141344 MD5sum: 496c3c0f350c74c6d185a871b03c47b7 SHA1: abdf2e61e83871a770fc35bda50aeb4c2bff6b96 SHA256: 27d9663500a5fe5b85743fe27cef8765a906e9846b470576d3ecd1fa7fefc3f6 SHA512: cf25c6d531a25a082e7a5e376166abe9990507b48baa58ec6a655d29244f09e1e2cf8dab7a80cfb0b7c3332353a270a7585bd0fde7c92e0e89047d2011df0cf7 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/](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](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: . ```raw [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: . ```raw [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: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.1.1), zenoh-plugin-storage-manager (=1.1.1), zenohd (=1.1.1) Filename: ./1.1.1/zenoh_1.1.1_amd64.deb Size: 17460 MD5sum: 662022fec117255596014231a5c705d6 SHA1: 607c3801d5a188034e0218c74f09a1cdda91156d SHA256: 4e68bd11d15386e8978dffbe07cc24c0508462b964b6eebee6ba64eaefbd4614 SHA512: bd991b02392e209e7d004173cf20f74852c227b753e065c148cf671ebc5702d2b3bacaaed8974b4ef7971489b0c6e6d7747d9f6e7ff4a51e5e08c4f6ab3c4a22 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: arm64 Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.1.1), zenoh-plugin-storage-manager (=1.1.1), zenohd (=1.1.1) Filename: ./1.1.1/zenoh_1.1.1_arm64.deb Size: 17460 MD5sum: 79d8ad964d86b48a791ec2d4433bf9b4 SHA1: 7a3f0b48951ef6e39e9d0388484af6c72178b0f5 SHA256: 7dda9d8d5f0a619292bf6504a0c3476debc1082510eced1bdd5c8af0fdd7ad33 SHA512: 5a0658dd2bbd7b2134ca58b0ed0c71fb4d15d767f810cb3db39e3b468cc0f011a846afec0de101d0850025f9f742b4fc8bbd0d1984b9b1e4bbcd4095f2faf022 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armel Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.1.1), zenoh-plugin-storage-manager (=1.1.1), zenohd (=1.1.1) Filename: ./1.1.1/zenoh_1.1.1_armel.deb Size: 17456 MD5sum: 0ccfc32a274026ac6eac0d2cd91b9772 SHA1: 5a6404341820c25d9c3d5dd855287562174db602 SHA256: 694f8986d94868722ca8796d71278a2a9867f857169a1b12008f15d37ab11444 SHA512: 05b316d0d5c6fe379acc3bd16f006e581cd965e2a527e7bad2f576fa4da100f615f1e7d55bbfd46d6f77ea3a2c25dd8ffc423d000b390155b48a15d767cc500a Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armhf Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.1.1), zenoh-plugin-storage-manager (=1.1.1), zenohd (=1.1.1) Filename: ./1.1.1/zenoh_1.1.1_armhf.deb Size: 17460 MD5sum: 10f38cd8ce4f6e4009513c24b78a3caa SHA1: 770d39eb50e5f23e25942463bb812c9f5feaeb58 SHA256: 8ce59535cd7b7fa6de2f53733747ccf8769501d4cc915c16daa826cb499cd93d SHA512: 1d605ac4eaae92b9f3a0b325db19d3f5e87696b3d60de8972ade4077fef7799b6b6c65daadc8280eb4b0b9e210131f040be712976144fd636a77983adc5cd624 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: amd64 Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18482 Depends: libc6 (>= 2.29) Filename: ./1.1.1/zenohd_1.1.1_amd64.deb Size: 4509268 MD5sum: f35a9adb55548487bd3a5956fbbcf7dc SHA1: 61dcf22645d58cb421c246df29e59b850de4a556 SHA256: f8ecd969adcba41342c59a0236714a54dafc3d950b0084b46c28e2ab2aae1572 SHA512: 987d676ffb1586fd2f4b4c5a88dac11ecd876d7def73760fab0c86dccb7689f441ce799401d262784de69df66c0a8cceb0eaabaec3aa68729bbb7d5aa19f529c Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: arm64 Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16590 Depends: Filename: ./1.1.1/zenohd_1.1.1_arm64.deb Size: 4053452 MD5sum: 3d8786de9a0d6e266fd2c1c298853a01 SHA1: 328b0ea5ddede61b8c40520e778913bfde0754a8 SHA256: 5652b503def2fbf97ab15788311d583c80c39ceca19a0dca5a7b5ab6de0486bb SHA512: 1c2538b38e739ae207b51dea002b37d874f6e41e5a454de0f0e4ec9d5439cb674bca8be81b33f217d6125a2ef3baa952629674d9c4b57bc80732ffdfa7a713d4 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armel Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18039 Depends: Filename: ./1.1.1/zenohd_1.1.1_armel.deb Size: 4432852 MD5sum: ace86fc54641f7e067eb8553e46e4630 SHA1: 7f51bb0384800726c1d69736d6dd31ac89257764 SHA256: 95cda2b696f157e0165e968ae1314c4bcfcea069ea4ac8b22db9132566a075a5 SHA512: 8ab082f0143e1d2b3bcec41bdceb295fd35268281bba3e32b86445a08c77bcbe101488546870baff39e835cbd6f253cbc7c576e939f104dafe0e13967f4abe81 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armhf Version: 1.1.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17809 Depends: Filename: ./1.1.1/zenohd_1.1.1_armhf.deb Size: 4484336 MD5sum: 48f00aafeeb9e1fd9a927a734ced8035 SHA1: 93840ee93b630124e23581aee973568e6b1b2ed2 SHA256: dca5595bdb8d4f9858c92d3cb51e71e6e380134ce10ffd0c03e97358e2d46daa SHA512: 95b9a54edde293d32c5e7fd30cb177f58fa02586b0526f4ee6b499a6901b53178aa3b42421daf3abac597f70347fcae363a184316a4d43587e2be3d7167c16d3 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: libzenohc-armv7-dev Architecture: armhf Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30919 Depends: libzenohc-armv7 (=1.2.0) Filename: ./1.2.0/libzenohc-armv7-dev_1.2.0_armhf.deb Size: 9507268 MD5sum: 103480ce8e1d5506f54de0767c4a22d1 SHA1: ded11a061c88d79d4b5d7eeb86bf416455465ac7 SHA256: 353917c84b69ea452366a4ec1797210471099cc8c522175502d7fa268f8c00ee SHA512: d83539b5d497af513bda8d4d1eba1546f14e04a6e45d505f0ad8dada34b0e57e17fb7248cb0ce7d162e7aff63a38a61e030347a7e88fa5465d50627b42e04b31 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18355 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohc-armv7_1.2.0_armhf.deb Size: 7003068 MD5sum: 460edeaaa4165b0db248503f70bb6bf2 SHA1: 063a94a76be912d8904a817d5c9474818da4c9ae SHA256: 2f0373c98916a563421da6aeb558980e4da250d9992d9231feb86d84aaed231d SHA512: 6dc237fc6ab5ba38f744a5cbfc2110607fecc7f3d1bbacbfa3f53e93bee78c12ea2539e639c0346d910f3c979c175161c96bfa2958e8fe7ff4fc20ac2abd4ead Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 39036 Depends: libzenohc (=1.2.0) Filename: ./1.2.0/libzenohc-dev_1.2.0_amd64.deb Size: 9063078 MD5sum: 75f0b5a1606beb06312f31c3f38fd550 SHA1: 74cc2f3a63da4d2ca1b0cc6030c574c563e53c1a SHA256: ba3d1f28e7a8c0a4a2ed5e457d6cf052d2aad399d48c88d81dd62b77cdc52e57 SHA512: 9a2b0730d6fc279c7cb3c08506224d70ed11214c9b0f3327164035ffa2607179c34ed50a69c7fba030bcc744ac3cb5ada7f9674fc6f9d838d3dec0afdc014c39 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 39380 Depends: libzenohc (=1.2.0) Filename: ./1.2.0/libzenohc-dev_1.2.0_arm64.deb Size: 9156690 MD5sum: 74993dd4339a782f92ff9c4694e06c5f SHA1: 45ea70be81c03624c48598c803a7e19c93175c68 SHA256: 31a7dd8d9c3164d8fd9c4a3e146f30d170fbd3a3042e32ff86b7435c18db6c28 SHA512: cb07bd12013300463e90f5341276ca7ec90dc3ba37b98329f5a965819487e0a700185f0fef9be4abb133fa5a22c741c531256f4fe19ebdce040c8d17ab1b3e19 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31772 Depends: libzenohc (=1.2.0) Filename: ./1.2.0/libzenohc-dev_1.2.0_armel.deb Size: 9689140 MD5sum: 391f7352651cc29181379d326c587cb7 SHA1: 49082d6734cd51fde57c80fd33473e54911cc587 SHA256: 41ad133e7d906abdf8bfe015827b40168422076c6efe9846898aa5059a67f21a SHA512: d657e1eee3b6aad3d68dd5fec1343276c135d6559b5794206a2ac9fe0dacf1f977281698c90d1cf7610d4ee40eff30cc128f5f16441fabec3301e0a6d8a93df2 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31934 Depends: libzenohc (=1.2.0) Filename: ./1.2.0/libzenohc-dev_1.2.0_armhf.deb Size: 9800858 MD5sum: e2e78bada39d36db6590528cda9e4213 SHA1: 0d08b03208fd287b828b5cdd3aac13c3adbe904a SHA256: 597ff1ec036fe3b82c711e492734edc611e955d45ea46b78cf81456e3b186de3 SHA512: 1e2d27bbc35f368df0ee6489ba9b3e05f20af3ee18b435dc945bf3941d839cb7f0d510228d4c690ad471de38cd67fdfefd09fee966cafa1eaa1f6a3663a48894 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 34909 Depends: libzenohc-musl (=1.2.0) Filename: ./1.2.0/libzenohc-musl-dev_1.2.0_amd64.deb Size: 8829808 MD5sum: 711b4c535a1d7e3b2bbbd517590a410d SHA1: 0ec562c0b02a27a3c648bcf17e493706fe470a9e SHA256: 8aeb2c053c30a12e1ff0edccbfb8bb45664f40d5a1c4b052679a6009a9cefb9c SHA512: e24cb31739ad7196ab3f766044b43c3c89ca89c18d8d58c9d881bbda7c8f5ff5e1cd4ac2ba9f7a7e435b34df23cf02c7195f2f5bf50b5b1fcbcfc5f7a2819d09 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37381 Depends: libzenohc-musl (=1.2.0) Filename: ./1.2.0/libzenohc-musl-dev_1.2.0_arm64.deb Size: 8905148 MD5sum: 1bf33a535f1e82e3b1d9b54929393d36 SHA1: 57548e0697cbeff94639e391582af47ea9cb4e2e SHA256: 900f170ed78a696a5c9b0773931d3cfd59465dc3e3beb592f56da25807048604 SHA512: 91ee1c454eec4820fdbcffb9003565c1e1f47726e6ad757172d3887b19c8b844b4d367b9d32f68a10fcdd910c60af3212997e2e2c5e7757a928ff6e7f7b6bb17 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18463 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohc-musl_1.2.0_amd64.deb Size: 6701066 MD5sum: 9dd0c14dcf1fb990b62be46bcd3416c7 SHA1: b52888e203d7f16c4ccf6c54f94c885b4fd2ac4d SHA256: ff5d081e7b8bf3b67eb75fd92116f435841fe94849f599f289cf8a2e388c646e SHA512: 3599179b3593270b3da1adf859a1575accfb042ecc551216dca909d204bf39c88ea66a1cf609b0063ed3d6e06e99a10020e02506e75c2bf27d9c5bf7adaa6517 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17132 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohc-musl_1.2.0_arm64.deb Size: 6382266 MD5sum: a1e48fd77c6b405ebdc49728a89fa297 SHA1: 4f30a360a239a2c524772c989c5c850133c5b6f9 SHA256: 25ca7b7c110b2c700f02a0d155614ee820a99d58b1dd46f9cf4b75e83b87ba99 SHA512: 9519c3a3d2e1139bb1068338a52cef3e8e26850efdb962219fd389e5e1f0d33fd21b3a1fe310f81ba94bbb5d0d1695a274aec070f17a27bd289b49c126d74468 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 19050 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohc_1.2.0_amd64.deb Size: 6711104 MD5sum: fa0992900acfc37fb9e868e109febade SHA1: e8c50a8f67436413bdf09ebceb423724eacd70de SHA256: 313e40b5f6527dafcfc3f735f025d745c310f32dfdd4ca5d62548b37c662e6d6 SHA512: 3348010e1534751bcbb4764d46c388f5e23040258fa980d83f6b2cda83790af3272e46a1007aba0bb50759594023486db3ce933827d2382195c2c962db4726b8 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17477 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohc_1.2.0_arm64.deb Size: 6438348 MD5sum: 380f73cf880ba1a4deb60fb9d09a79f7 SHA1: 47659a93d926df2871f2006ea47645e274da9a73 SHA256: 493d0dd0157e38e0d222fefa55a724e58390a0353ae60e44b5bdaae7236f3fa7 SHA512: 9f756afed1b108e8011da5d59a8f39bed2a24fa7c03e802f948fe92ffae910b6bf1b394937a1ab54cd1d64317e25cb301d3227bde1188d5bd63762f8cae1945e Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18765 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohc_1.2.0_armel.deb Size: 7094908 MD5sum: 027d48bcdccd5ddb920aa728f18613e5 SHA1: a17850bbc118c6db4e51cec0d5b9b3eddc8ffbb3 SHA256: 629190876c95bb1158a45798d3735499d5f51e61e61a9a6aea18861df127b2cf SHA512: e7e11955477ea77516ad6cfb75ea5319bc1cb9a5ce298d18dcb8338eb505f8f50ff3541816a3a9b20f19a87c599f0421090b5feeed953aae58cbde00d3617983 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18748 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohc_1.2.0_armhf.deb Size: 7171690 MD5sum: 99440026a2fe8e317170e0fb8cd68b2e SHA1: 1d434f7448d14900eb9797b16d4f177793f2cc00 SHA256: 46f2426f2d79dcceafd35ef69bc9f271db9882b9daac9b838c11eb6a12da3649 SHA512: db6a656ce8f3dcc1decf4e9d06c712a1a9df6d10efe2048d9ff5b347b4c0e71828369bc6b4f04f486236745111dcdc4e26cbdc0e8b62da8b25fbe8032f73b02c Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 442 Filename: ./1.2.0/libzenohcpp-dev_1.2.0_all.deb Size: 56660 MD5sum: 80c7becf7495fc9860e87faa14e6516e SHA1: c235fa655cad2f2ae594f458732bd1130aad1ccd SHA256: 201569d96799bce040461368f64f5ff727944eb2d0ef68c75c1bb977b7c4170d SHA512: bfb206d8c36f2cb62ef1f6d41a30d4fb0e59f12c5d20e41591f9b063ae52e095a2937a19f008420905fa2f9e4c95dee17999ab6832f7b2dadfadb74733c23422 Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1207 Depends: libzenohpico-armv6 (=1.2.0) Filename: ./1.2.0/libzenohpico-armv6-dev_1.2.0_arm.deb Size: 241196 MD5sum: a3496ae0ccbf530ddde4d3bca4f71ed6 SHA1: 6ef85387033b7601dab53a6d156eaab469de041d SHA256: 19e82ce9a1c43cb9bf75a60d628155fe1028994ed55f977a520ef201ae0e98cf SHA512: 598dcbe4ec3a067fce767543b47e7380773dc77ffe6bb130024778404443fde2adce4df3d529446adc70c13935c85a501499e3368cd2676234351d5c40e4d119 Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 349 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohpico-armv6_1.2.0_arm.deb Size: 142492 MD5sum: b807b68bca9cf6024352de0b90e0c046 SHA1: 301232da2ae62abff65d8acd264323c9752e90fe SHA256: a6a941050b0f12bda5f3115d7f73b1f8542437a9d4241bf624348db1f1ac3e95 SHA512: 7465399f6cd24a6ab9a8fa005fd8babf8d0eb6e0738194c4f29769e1deb33bdb3cc78101f8eda408fea769d165319d24b49862f80e772bed73c6eca6c0d938b4 Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1200 Depends: libzenohpico-armv7a (=1.2.0) Filename: ./1.2.0/libzenohpico-armv7a-dev_1.2.0_armhf.deb Size: 239704 MD5sum: 570b39876e849cd9fe03402298bd3ba6 SHA1: 0c85f3c14f6819b95b05c9126604cbdf3ff30003 SHA256: 751d3bb9bc24ffb21fde05aa6026ae6a6b3e77f9373592815b14c5785987064f SHA512: a1ea00deecb8cc0c22fa37d7e530de747983c99ce4ec700e64d9d17c9349145518433b98d4a2eebb48dbf212dab399f6bcf3507dd7e2aec3e68fc477f7fcc62c Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 345 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohpico-armv7a_1.2.0_armhf.deb Size: 141914 MD5sum: aabfe6b5529b9a1f296a2ac674f5052d SHA1: fab9bc09c91ba9dff61b2dce0f05d76a46aefe4e SHA256: 9e9ec96f923150f2a6a301d93a33daa389166132684bac27dc0775b7aa0fe0f5 SHA512: d652bea6d04991db0a855c741e93e88f6924eae1b32065908ee64b75cfa4c8d98ea9507f28666e5dd63468d69b51cb2299f4878296ab66d10a4b58ef05484971 Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1450 Depends: libzenohpico (=1.2.0) Filename: ./1.2.0/libzenohpico-dev_1.2.0_amd64.deb Size: 287070 MD5sum: 9fe137a23710e75eef7318bf6bfc4849 SHA1: ddba24a75bacf6a3be9b792c2917ac4021505787 SHA256: cabcf869b7e0a6ce0184a2a94647ac9c42a98d9c11297fb7c0d347337a40544b SHA512: 9242464277f7b65cf24fcf076f9e588a29bb81c11c5115e199202be20d528615d1964e7f52d86c5becc6f8dc3c02a5f993e04b00dc26a10e4587394e21272b18 Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1206 Depends: libzenohpico (=1.2.0) Filename: ./1.2.0/libzenohpico-dev_1.2.0_arm.deb Size: 240874 MD5sum: 93cb7d2dc153df3c9df568e6b48f5b66 SHA1: 4ace7a676eff0e0c69a4802a7989662cb982781d SHA256: b83e72b59a69f0af144df3f25a4be92dfd73f3c2573066ba3647718c465d3a02 SHA512: c6038bf4930c16d3ba5f27553ee532471b5d3c680ca0cd21a565f99182a21cdf6c39e0ba3018bfc0fc4d8aff9220bdb60b37aa51c470d26420004aac8580b716 Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1461 Depends: libzenohpico (=1.2.0) Filename: ./1.2.0/libzenohpico-dev_1.2.0_arm64.deb Size: 283592 MD5sum: 95b523c8d8840ba639401d96b08d38a6 SHA1: a56690a8625e9c82258bc24090f3be104db52a55 SHA256: 8b43dd26ad3a1bc1cd72b1a165df449a75b4bd83e23c030a66a7fbf6ff883d25 SHA512: 9834ffd8cead26d7cb8c1d8071290941c579330a853d39cd228f52e7f811e766f329403ce3a77ce68b983f02efd66888d6d2498103717ee93745ba327627d29d Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1201 Depends: libzenohpico (=1.2.0) Filename: ./1.2.0/libzenohpico-dev_1.2.0_armhf.deb Size: 239458 MD5sum: 58ab49ad5506a7e1af49ba7a59dfbd8b SHA1: 689e0423f0a3d458914c9bb651a2b3c92713e122 SHA256: dbe282e19a1e96d4bc69e18b67b445845e3c9e857c0c4323811a084a1b5c4156 SHA512: caeca06f22de08d83438e6dce4fc7597888ad44592debff1e510b7594965481174e0297772bde7430ba81574b23b1f8500c768f4667f50fa08e28fdfbc8d6310 Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1421 Depends: libzenohpico (=1.2.0) Filename: ./1.2.0/libzenohpico-dev_1.2.0_i386.deb Size: 311812 MD5sum: 93969374362f6bc835a369d14cd4efeb SHA1: 6e61e51d40f8034c1b610cd3cf1c93c392e73d3f SHA256: a7e24a2892449a961e9ea12eeadef22b843ddaa7ff421a28fe7404559cd58b2c SHA512: b4230d80685f7ea8227c1e547255ab9a2be7c6d87d1f741004c14cd70a4c6e67d81d09ebeef628909a2736fe9b0ab524b7a4cf64789cbffee8b4d98ac4bf98a4 Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1350 Depends: libzenohpico (=1.2.0) Filename: ./1.2.0/libzenohpico-dev_1.2.0_mips.deb Size: 271586 MD5sum: 5fab8657c29278777d87800da7c8950f SHA1: 6777dd5f90fd873c9301900fa481d15d84ddc446 SHA256: e3b08b10c01f7e5c0b1caa5c672a90b382da977b39f9c06af7dd34e2652d3c93 SHA512: cedb1100e7fec977c6cc7182994dabb6d5623fe54fbaeda0b2177e53516d0186e3ad9ef3c7ee5a21dcbb8e320545f2f2fb4798891de77fc970215d9651caa052 Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 472 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohpico_1.2.0_amd64.deb Size: 173514 MD5sum: ff3f0ff44472cf4265a56e416eab3c2c SHA1: 493f659b4e9a407a78f31050dfb318731f7ed9aa SHA256: daba0e0036305a01715bff5f712169a07c13923bf0a77816e7072dc7abd8d34e SHA512: 5488807f373e2dbbce8962eaaf219f8e523bae1c2d1a1963c12ed477d82d36ccc79975ec514d58b8b5ee5d8902862df79b47982b0c77f07a458e7c7f66373da4 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 372 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohpico_1.2.0_arm.deb Size: 150730 MD5sum: ad2a28f092eb430b94e5bee9bf32f670 SHA1: edea53c10e43236fd322618ff49df28520124b43 SHA256: 25a856f998dddb98c2a60dbd6d0c6efab0730173d52de2202347229adad23362 SHA512: 3113e4638c9f8cc8231d52f8a2feb454d9e62d87f34e78732d85fae4a137955a5b9616c651e3af8ee0bee74c05b76ce847d4bb2398a7536a6cffcc7228cca5c6 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 486 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohpico_1.2.0_arm64.deb Size: 171688 MD5sum: 355c9287ab927ffe9d31d4394765bb93 SHA1: 81b3daf7001e116f9d4c008872a005849d7bed13 SHA256: 4a7a0aa4e72c66833a481f173150cd2db214db869cd671592441093b370ae5c2 SHA512: ffcee1b90f3cb04e88a2f33536628143bb52210cf4950543c6d6b06b6b8863a2858b045b21f8c5078b7238e9cdc19cc62e2facf05d2783f3a23d7d75e3d64df5 Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 347 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohpico_1.2.0_armhf.deb Size: 143018 MD5sum: 4b0ecc4d67bd243ab9cc562d70f2a452 SHA1: ac4a27208ccda5921860438ef0ebdef101d91fd0 SHA256: 3968a71bcda09a2b69321c0c7758c1cec97f9f0db2fb8c04083be7a3573c37f6 SHA512: 5cd41601e7cbff3276adde6901c55118713358d1c9414d64bd9d55976d012076b92f6980e10097eb16da598108280ab294dfa45341e35df3e9205ee807399c8b Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 503 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohpico_1.2.0_i386.deb Size: 197176 MD5sum: bcba54b58e121952d11c4b0b86a6e87e SHA1: 9aa1b29db7659a1d714754f8e002694fb236f979 SHA256: 4e57804e7863ecd5bc6517990513a22b3b0396d8313599681b7db0773a80b21c SHA512: 3005e054e6549a8032ad1986c3a722ec179f2134b921cdb523d3e8c082fcd2ac47950d0643e1655cce9b75ff2c6d373594c5db86004364e4569d75f23b10d3bf Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.2.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 453 Depends: libc6 (>=2.12) Filename: ./1.2.0/libzenohpico_1.2.0_mips.deb Size: 155720 MD5sum: 53907770e31db8c720d6ada36e755042 SHA1: ba2ba8077550910ad7a673606e17115fea90a14b SHA256: 0582312e5cf55389d7372d751e48e522f47ced5204f058fd10d8aeeb0b449511 SHA512: 7174187ee7b562eecf9c3129ae68164b6fd9d3629c89b11ee1196b5c00a6888e006cc7bb4e226dc06a624e7c5e74c55a6b8c883f047848233c9bb2970ef7f669 Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21693 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-filesystem_1.2.0_amd64.deb Size: 4779976 MD5sum: 04aff44b00f2fa72f5bf6811b64bc2af SHA1: eb7d01da3abfca4ff9960cc9b803c5bc8468d714 SHA256: e53f63c28d7bb8de59a52be1bab56b791483b55c3902f1c7879ba6f0d72664ef SHA512: 2cce1c311d737f9b88802f26022b15cd4dc09f115bc6ba4a8e99ae1db6cdf0b10c27e8ae3e69f334049c6ed1e37905bfafc31cf64ec4d16d3e735a9455181238 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19741 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-filesystem_1.2.0_arm64.deb Size: 4279292 MD5sum: 9f3fae2501130ef9281372229fdf325d SHA1: 0944b5ccb32536c8493e7a9a7638ca5cea6e9afe SHA256: b608a667b8f666cedf73913d90ec2c4034fbc8193415d31049935b7afdfca9ba SHA512: 56519158a5cac8850cc8fd1aa8aa31e2f8b65ef4cba40c7a7c2a8b53647090a5cf10dfa97fe3546c71f5821ac179668b63524e9017961d08d1979e2b18002796 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17317 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-filesystem_1.2.0_armel.deb Size: 4055668 MD5sum: f666eecab6834cc554aed1d6897162c7 SHA1: d536d2663bed83d5437b302066cb747481f1c668 SHA256: 3c9e799040df5d26f3fd1f2a927947fdaac3d2397d2dfa17b2776af3423263d6 SHA512: d291fb3f53268a3de12163f77c0c6b41535ed2ddaf76a69ca994b838b3340f76396a40199c5c38a6518028c687150636b6faebdf3de2d5043c1494cf4df2910b 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15232 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-filesystem_1.2.0_armhf.deb Size: 4161880 MD5sum: ac7527b5b5415536fb5d68c5fa44cd56 SHA1: 25be0dda7d495a75e8bb7e286a0844ea44527eea SHA256: a12bae389be4c851e4f058f91a615b375e4e2b3510c0905228ed600c998ccb4b SHA512: 3fe1f92e3f418e0a60494986268a3045d0a3d5a710d238385b2bb779d39aeb7f2d4542964705c07069f59fa9061dbbc4fb31ccd941554d3ba9ba3afd06704e47 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15717 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-influxdb-v1_1.2.0_amd64.deb Size: 3109824 MD5sum: 9a0f731b0ceefa60d32f1135a56404c9 SHA1: f3665a36f65b3d56ba39103ba017f0fd6d2c1910 SHA256: 5ca9c291b7646c84d0859f968645a4434d7d8314d5ce3dc4f2e3854135c8b2f8 SHA512: ead74ea636b13b3fd474e2715b3a18edaef7c58d041bcaae01d72a50f50da24269b4a40a64e41e3ffd35e6efa6ca0233e69881211ee66f0dcc346ea93338bc4f 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14048 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-influxdb-v1_1.2.0_arm64.deb Size: 2794680 MD5sum: fa6ef6bfd7330564f156655bcd6b7220 SHA1: 4e836adcf32e2a34e7eff8dd2e90da02d795a9a0 SHA256: cce1f927d0ec8173656e86d5d7be5b7a744ec8b68f260a9411fb8efa02e41999 SHA512: 3beb24c0cc578e0e4076d52f10bed96502acf210403dd7cd86eac53807e0b049a149b6c674fb1f4b6684e2c7d6d0eb87bef507d1ef035decc71eb96c1c55002f 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11801 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-influxdb-v1_1.2.0_armel.deb Size: 2534544 MD5sum: fb0dfe47f862966d1ba3f5ec92d0befc SHA1: cd14d522aff1b1fa19cb197c88c7e0e06ff7346a SHA256: 8fdf57c7737f9092fb1dd86e018241f82cf8669ec12ba21d04f248ecba9fb266 SHA512: 188c04aa17abd2903e04759f391cc21f270eeb7135061174188356c849d6dbaa43bc0a2bc1b2f048845640a17068a478e2ce07605c7e1954db44e1ff5660f594 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11679 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-influxdb-v1_1.2.0_armhf.deb Size: 2528752 MD5sum: 54c4125b763fc336ca940c295c4e06c8 SHA1: 9663b1e541e2868a5a68ae25d0b6ceebb22b83e8 SHA256: 96849a017a60d4a1dd6acbf8607677fbbcfbd7ed07829588dd5ad34402ace12e SHA512: b3f3160a3da2d1df2d717faef556352547d06cf91c29b0ee296d29bb384dda8e252869e0a5584add6cf13ac786a71b2dbf2172b79f847ca2430ff8e6e1789e59 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17252 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-influxdb-v2_1.2.0_amd64.deb Size: 3779820 MD5sum: a87873d4cb5cea3197d2821e26f99183 SHA1: 824a9dae1c38532641a3361846859eefbbdc27cf SHA256: bf6d3efe5801eb370322867e6055b973f027fa9dadc44eac0d1b9755a99feaa6 SHA512: bdf57720f3dc7a421012a9c8da04d9b3aadaad590640eab3346b0e4ebacb67951ba25a83d5887cb4acf026d5d5609f77ed9d71124b4cd92af703650a4379181e 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16233 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-influxdb-v2_1.2.0_arm64.deb Size: 3467036 MD5sum: d2c638850e4c0556e3fc659176888886 SHA1: 351c6665857573c44648c97557960669718d8131 SHA256: 5b77bdf5fd499684ee4205416376abe21ee5fab77df5faac7db048cfe42301ff SHA512: 5dddf2384efce64d4a80bfd0b7a3782f57c730426c9f671f1a773225ba9b33f043798705483963680411dc93cd16278fe4ee0f77207dc1be0263181672fb7183 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15493 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-influxdb-v2_1.2.0_armel.deb Size: 3445424 MD5sum: e032b156224edfc807c54c9f609133a2 SHA1: 94cbb51586b02869bbbd5eaf64409587949e1623 SHA256: e82f697165041e04ee128d9c4c00de86d0a845f5a4941d251309744c9b237119 SHA512: 3ecdc480df586560d4bc9e6ecd1dee7976f1925c330907f06478413145387c0e2dd3b62f1dd16e2eed7a304832a76a474c6976fe2fc2a704acd9b3a9443a450c 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15390 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-influxdb-v2_1.2.0_armhf.deb Size: 3485604 MD5sum: e728410e3033c3e55b036ed65053c8ab SHA1: e4078a7885118a034354a22ed6697cc49333cf0e SHA256: 17e45546836084031e0b1fbfdf84431624eb297ac02a0f02e960394db50d9bce SHA512: 5bcbd695899605d5b27b1259368752052473a5f813701674295c09837efd7eb48137ae895066ca6f0530f072be9c1b90322a4dc4829db8fa5e04d72895016671 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20233 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-rocksdb_1.2.0_amd64.deb Size: 4502908 MD5sum: 00c6ce135db4053830567274a9f223e9 SHA1: 390c1be93b8cc6edca6207eb4f6a45e63a8ce868 SHA256: fc84673ba90e3a955d43f972e9ca0a788c18e7581c3d20ad0044cb171e03981a SHA512: 63688def335669335ba8477e784adc10d125fe0bd1906c8b0ea75ec3a5834a4e9fe1a73368de983faa35ec153c4fa9219ed175929873113014de91b6d1043000 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18295 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-rocksdb_1.2.0_arm64.deb Size: 4029336 MD5sum: f962ed9491dfb46d8fbc08cbc831e2ad SHA1: b73dfb00213aa5516d3b9364509685241aad3ae3 SHA256: b7add382939c997d0d576fba13181f9256f62baf4c64647159fd9a9bedefb594 SHA512: 0048f631d9117613667d08de3ef9d2aa8ba5dcdc4eb6eb1a24155a90caddd816a004f2ca8bbf4a6de9a7d16ee4de0a5e580c3ea93d4b2f87b4312d787d653d0d 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16096 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-rocksdb_1.2.0_armel.deb Size: 3838324 MD5sum: d09e6bd3a23dcd4dba585dd29b938403 SHA1: 6cbd739418f86194eacba32a59a98c010a64cdf4 SHA256: 8a638efcf11ed510c9e9b2ef8a4757af4395187df2f52cdc05cdaf2df76268c0 SHA512: 3ce75bbd47ad7fe10913f5bd6a92b6e299701b59b6a06d4ba277c18340ca92228ed0e8a96203cda3e48cd79efd4cb62e8f98e66f51221dc7804a5ff13dad5121 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13990 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-rocksdb_1.2.0_armhf.deb Size: 3947220 MD5sum: 4ff2631168a33025e4fb86d4a133783d SHA1: 96c74f57afc50de287d05b590220ca727b22fd17 SHA256: 79f47ffee5f8fc0d2f72ed612b383da14c71c6707ed84d971b935923048dd6f0 SHA512: 7d55064cba9f9b97e42b013e08890275c114426cd2996acc09d2db1f51b125ebf6d03bcf4f47c632ad5cde711f6601f7220f87afd83976a59cc64f9e32550203 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27370 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-s3_1.2.0_amd64.deb Size: 5504572 MD5sum: dbe0fddc0875dba7cc6ca544e7ea06aa SHA1: f9f29b558d36358bfc3921999c3f41c6790e41ac SHA256: 2b6608b494dfcb9f8f63e9f16b7cddc126dccb4d619ead7e67cee7d948432323 SHA512: e9848cb0864fe8aba91f339385325e0fe9dd8697eac2c2b9b4de355946bb6a52737a9f5308b567893dbd11356ffbf20485120e8cf8737e15a2879c7e829ba452 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26636 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-s3_1.2.0_arm64.deb Size: 5229968 MD5sum: 9ca3d7c20b82bf23f45cebed9dc1c17e SHA1: 38889f4fa9c98ec357627e51df0eb21b0875f2f2 SHA256: bbbdcbf0816a90af8fb650d2bf624b0a1d4051dc1ca56fe241b0f84c0b9afc05 SHA512: 8eac837dd9b85397d9f8513a6b6ac5dc0fbb4134d73bd7c966c46286cb34dcf27a42ee877212e1f9532f6d559a57289dc82f09bb0c7a8fd1492ac9a6604b7bdc 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25355 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-s3_1.2.0_armel.deb Size: 5081216 MD5sum: d5d130aa94ff786aa6776803ca66d53b SHA1: 7037b393eec3fc64b44b176c2a05cba62a6f77b2 SHA256: ba2c967955f336afbae029e74109490265a5fbc7d07d054d495b0f5f6dc48c4e SHA512: 77eed3da943a4004826e50f12ae3d32e221ce8fee957808845ecce58bb812addb48048d7a69a674bf7ad1b5f759c43d253771c5ea6fee852af1ae20c619cd6d1 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25138 Depends: zenoh-plugin-storage-manager (=1.2.0) Filename: ./1.2.0/zenoh-backend-s3_1.2.0_armhf.deb Size: 5140700 MD5sum: 217b41294a3a296355c44c6ea2278a4e SHA1: 89466485e10a77ce2643b7adddee2504f192d7f2 SHA256: 5be3a3e54dcce4bf5dea6460e20ebaa6c6c2629435152c3f4ec59755901b7aac SHA512: b88d837b86f265595622668dd60afc3e2c6d1406e533f57ae37b210e7177757d1903442779122dfee9e1a85ef5e90dc944d1625f2d4b7b6de204ba0bd171a8d4 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-bridge-dds Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21232 Depends: libc6 (>= 2.29) Filename: ./1.2.0/zenoh-bridge-dds_1.2.0_amd64.deb Size: 5327796 MD5sum: 9b9af0678a18c730cf25a8fcfef387e3 SHA1: 02c992dd84ec02ae729fea7766273b5127723387 SHA256: 26945d4c2e9e245eeec74d8b346e387c336b69440ff2ebed1e56411dcdf54c39 SHA512: d83327866e41eca6caffb16f4dcef25cfdb786be292e0759e54c3af25e0a871c9decedd32ea90a8199ea63d29cd2e07448a638ce7fbc53e70bfa1d6c1f6b8cea Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19409 Depends: Filename: ./1.2.0/zenoh-bridge-dds_1.2.0_arm64.deb Size: 4811656 MD5sum: afeac9b7916c03f33c2b60352da6c273 SHA1: 2ed0ed135326b0cf97736be3975e92902c6cfffa SHA256: 45ef8d2c9aae2c4f1dce1c5044dc8555604cb12250a693da834190afe54dcd45 SHA512: 702d8a7f6a934a8a9bfbb6a4c6669ac8cfa13dde832eaf7c0905a85319a562ef15553a597e2d9dce76b2c8c10e797042dd82a0977b8f18b9515ca7e68f0ca442 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20510 Depends: Filename: ./1.2.0/zenoh-bridge-dds_1.2.0_armel.deb Size: 5102968 MD5sum: 2f7864990fb5ce2f2787312ccdec6646 SHA1: 0662192b7e033de0da8e093075ae2d5043925427 SHA256: 9cb23955326dac676985e50a1ff16e80e43b2ba810102936ca6412cc429e0d80 SHA512: f319913696b41c1a0763c36c4461e54ca36bb4c0f10f0663ef89fdbc50d0852e1ca4ac8ecbd722eaa513e645bb2c7d5bc3f52d5ef0e943b227b8c9de14d326ea Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19976 Depends: Filename: ./1.2.0/zenoh-bridge-dds_1.2.0_armhf.deb Size: 5149492 MD5sum: 10c4e836216872869f6310c8abadf405 SHA1: 1dfff1cc72dbd903284674a3d193785bbc038f86 SHA256: 5e71a12974c34ebf6006b952dc4341fc12e0c5e9f75b45515ce2f57fe2f9b4b7 SHA512: a5bbabdeea81cf146247c9e3f707fc57e1ea2ece354f5dffd2149bd810f1bd20e7edb940d766eef8f0efd08dd51de872665603915e387063a49779c69fe2416f Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-mqtt Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21262 Depends: libc6 (>= 2.29) Filename: ./1.2.0/zenoh-bridge-mqtt_1.2.0_amd64.deb Size: 5022556 MD5sum: 6285723603b57fc6da0c555e859a74ca SHA1: 187af31e5281be1e24869af507ba4a24703212cc SHA256: 8ce3d0c99b09d8bb09707ecd91618deb1184f332d63dd0f01101f0b1ba635e41 SHA512: 5ed81fb6357f4dd24ddfaa31e6475ee37f58bd8f4a472c3b6a10a2c7f0ff0953159b2b233b8356083d71df4148e231c26561f44404073eae191f992a273b9917 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19468 Depends: Filename: ./1.2.0/zenoh-bridge-mqtt_1.2.0_arm64.deb Size: 4536444 MD5sum: fe51837f509c59908c28cfcd5a85a6f6 SHA1: 79fbed656ac4021e1c2c85d6161070ac11d63237 SHA256: d47c5660fa5ff67775a1c10b404204d9c6fa46d64d87448f72c3fd64d7764223 SHA512: c37e00e746aabcdec990aebb212672a38bac56c68092fbf17a171f5b4d69e22fce7402d6114cb02c5236c2bdd8397ec2c798cac00a5498680d614cfb59e2d071 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20717 Depends: Filename: ./1.2.0/zenoh-bridge-mqtt_1.2.0_armel.deb Size: 4846836 MD5sum: 395c82879e87d4bebf5b42ce10ecce08 SHA1: 1eda198a259650c3effff5c0296d2188febab0e5 SHA256: 97cd932b186714536d2cf182caca35ed2310f381920904a8c7809cac06c4f4f1 SHA512: 6d696fe6b38d84ac95dd3b3b5e38d66061f3e67fe61da0afd63a5e1e54d643db8cfede121bf1f92c2574df943390bc8858bd014879900c835921c89d2f3c101c Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20424 Depends: Filename: ./1.2.0/zenoh-bridge-mqtt_1.2.0_armhf.deb Size: 4874736 MD5sum: 4061d079032bc6429adfb011387a2f08 SHA1: 62d807bce8df9ec08b699da8c038fe37387f2333 SHA256: a3c00626aa60b9d8e9c172e180eb5bc2e0659937e22d86417779a7e83045ed29 SHA512: 96cae2005764ceef9979b18824bce965c80c4efebd325818410f168c3a916030198dc9c7b8b4e393d73cc78851776e1d85762b1807f707fa8e8db23063944137 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21832 Depends: libc6 (>= 2.29) Filename: ./1.2.0/zenoh-bridge-ros2dds_1.2.0_amd64.deb Size: 5439608 MD5sum: fe59228681ef8b85dcb477a42153249b SHA1: a7a21f714e79ff9f83a5dbffbd500232e94fee7a SHA256: 8b8d0b4711abd7a871ae69146d8bb1c53832addbac9e543bd716f72ccf54ca8e SHA512: fb7e51f22ec04da79e09fdffcf1548c0c55fa1ca652ffe9026b49207f62c1e98df2031f7202d9cf71f2c07bd9686be8e7f4d0b898e1095d9e350d19dc6164903 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19984 Depends: Filename: ./1.2.0/zenoh-bridge-ros2dds_1.2.0_arm64.deb Size: 4926380 MD5sum: d6b6584295b4bf27655645db23d0ca44 SHA1: d78f20f7a0c809c4c87569213a0d2e3294111972 SHA256: fa4b66c7a7de99dd06c789fddd12bc4593f196b5f93082ba2928ce84b4c1edff SHA512: 3c2200e9052bcda47f326be2aaa772c3bf0f85a6de6a9d1742eaf499880aa80c4e16ce5e775105f1bf35192deb6366e7c2e9a502504406f6f53492d49d3dc546 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21078 Depends: Filename: ./1.2.0/zenoh-bridge-ros2dds_1.2.0_armel.deb Size: 5212876 MD5sum: 14c515464e4abeb3065228b828d8dcb3 SHA1: c2003ad454faeee19356dc51f7516f7fa4e0a078 SHA256: 796f7334ddadd24ebb5b7ead083e1e36c802165c51c843b6520204486d328495 SHA512: ef267b200151739470e72b941b96714031f6faf904dd9f50812a5ba5626cf1ed5bad5feb40e840caeafac81a066588d9f921dd8f48b69af968e2da547e56e60f Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20548 Depends: Filename: ./1.2.0/zenoh-bridge-ros2dds_1.2.0_armhf.deb Size: 5268484 MD5sum: b099478b24a2ebc704b6aacf44ff3cc4 SHA1: ea2695d807f73c12ab3fb3888fcc162d8fbf8065 SHA256: 32f9886b1b717812d16e23dc50ef4df6df09f45cc1a5576a1cdac02c1d13e87f SHA512: 5a2d7590b4cfb19cbe10120421687ec6c9a8d4a5272159661f87a81538820b5e9a6e6e6afa9ddc0607bffe8b57c9dd8584eece9044299f2a79ee14e0476aa2ca Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-plugin-dds Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12794 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-dds_1.2.0_amd64.deb Size: 2585636 MD5sum: 3a57e5b54c20a3db05f87d865e3fb331 SHA1: 3a7377572377e29863ac32496619ec104968ce4a SHA256: d3eab46c9a8eb9d43fb6e19022096bbefcc5422e8db69c8252fee6b1afc8bd00 SHA512: 12ad8fcc6a3b5b2a77c14511c10be8a88dfb427bc2e8c7a294f35a9afd3e73d3f1b2d3efad3cc0252ebcb0b4c9633b8c0d2915240998fca3a2fa4ea5bdea4e96 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11611 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-dds_1.2.0_arm64.deb Size: 2353596 MD5sum: 5372016f53fb8769f3927ffe9f2b6ce5 SHA1: 5283e75d8f48bdba8860ce06983a871e7375b0c4 SHA256: 3cc0579fb042dce77976f8ba9265534497cc8119091615138c84257a3d0ae4b8 SHA512: 9f29c2dccd79806fdcaee5b33dc23b1a5508ed0d0b49905b4c0733616738d040ccd3127232023ab0a4e3572882c69aabb70e827d6ed69028f8d5ea6dd2acf271 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9636 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-dds_1.2.0_armel.deb Size: 2200772 MD5sum: 64001d8be8db1ace03f13ba1f9d61689 SHA1: a84d0f7d48196dd615c06488d9949e847ae4cdef SHA256: 2bf6734f6dc7107ed9f20d7f0b58b20d19f3257b235b5a4a3d5673cce532006d SHA512: 9b1ba996c096b2a7ffd3d514acba4bea6b6753b4159328296a0a8d36d15a3515d4065a4e78c943ce2d7be4f9f6bbb17a12ef09f9932e22af0a392cb57a85a7ec 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9257 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-dds_1.2.0_armhf.deb Size: 2205984 MD5sum: 7993cc9e17eb7294eba7e1da5c7f6242 SHA1: 826c7f17fc1465838f099719c0bfd390af943fff SHA256: 7b031753b2b28dfb1ec4e3a2b0948d7857a50ca92d57117d77dd7f83250a2d69 SHA512: ac9ef0ec6bc3aed4b83e66158718686c6abd5a574e87386a846bfb8700d7fc70cdea06b142b6bbc2805589acdcacab85c210b732935fa57f5c0cd23f1b920511 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-mqtt Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14173 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-mqtt_1.2.0_amd64.deb Size: 2904884 MD5sum: ed86331bc5ea3b2dff01017cfb862cf7 SHA1: 929664af20db937b8cb23a810ff52d1545f245a8 SHA256: 0e86357f3beb0b9cce61e1ad858989d477aeb9b53fd367bbee77f8888acf11bc SHA512: 03f59cb16ff65cdb82305a5a4dbf88ef628525174d91957748d895a938e4d1bc5361752bff377929fa6781c314b4ede8c2b39b27919c30fb7fe5fc46465c8525 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12884 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-mqtt_1.2.0_arm64.deb Size: 2598248 MD5sum: 907d9b3362b31bc4124a21856987fae8 SHA1: e05b4b6543e7fbb6dca86f6b60e73f8cca114c4f SHA256: 021aadb8f411830709ff64b68b1dc74a904cdfc4958f48de5cf92766bf44e29f SHA512: 8bfbe64ecbf3f422a3fe821c06a07867a672f0394f41169eba3c08025cbfd2570b7157541835ac724f30f8f765924521b45187787c01a657d1d3b684e01b3e78 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12885 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-mqtt_1.2.0_armel.deb Size: 2665388 MD5sum: 43d23beb424c5ef93ffca937e57f808e SHA1: 96e686ea602b46f22732cff67e4195afb834facc SHA256: 01ecf994ae4dc95a117d8c85359f4d4c2db3092aa9bfefa85ec05c0acfdf3f23 SHA512: 6cc861a0ea0d77ee9ae3499b9ff2a3ed95887645860fcdc7264248f5ffccf27a4b2d6c44c0f579f9d4480756b063aea08155982f61f35aa2eb49b243a82a868f 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12798 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-mqtt_1.2.0_armhf.deb Size: 2706648 MD5sum: 4e483dc71549a14c93b341ccfdc2267b SHA1: cec4b52215ec2d22d684e136f88b6c5482bd19ff SHA256: 390e3c914ddff3a6031c6ab7f95d39a3fa367860d394da2b7e5f8575fc734271 SHA512: a5fd0eec67244cc51eade6e49fb2ee61c43a82be96e6e97adf66fe8f3cf1c803343f6807a37ae041569d1a55107aba7e23f55213d5aeb5f268ac533ebb8581c5 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: . ```raw 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/](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](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. Package: zenoh-plugin-remote-api Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16289 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-remote-api_1.2.0_amd64.deb Size: 3466352 MD5sum: eefa35bdd4cc12cb81e5e120e45a50b3 SHA1: 983e8b019200b494bfe4e3bcc05e67526f0d1346 SHA256: f1fd4ad46aa3398e25dae745e2f81f62bf19cee820e29c456ce5c1fef9c8f532 SHA512: c48ffd36a0083906dc9c54a72f9fbd44358f7f3f078fdbddc61e0d95501d921716671c6a06894e71b4f981582eeab5283decb8e66630ea3bb1bd2f1e2852887b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15299 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-remote-api_1.2.0_arm64.deb Size: 3166420 MD5sum: 080cb9d29cea8f2b9b8211463f46f04a SHA1: 3b3f35e8505ec98e39df829d2f8e52de611f67d5 SHA256: a977e02360202a204c07acbf063e2c34ec217762c537b1ab1d215a433d1ca5c7 SHA512: b89b7ba6a4aa25b378047dd72e9c7343af5092e8a91af2e8af69bd7ad9c2efb87dd12c672bb3e2491149a1e6cd80c21fc2db345be9d93a5efea074e297871599 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14746 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-remote-api_1.2.0_armel.deb Size: 3130844 MD5sum: 8985040c3bf76b001d8125f50c1378f9 SHA1: 2e59cfce237e4ab4848e26d86e6236251e1aa420 SHA256: 0af06615cbf05dbfe80aecc5860b9d4231c73f5d3597157d09d30488287b65d8 SHA512: dcfd9b1f7fbc9828e96d6f27b3218ff2399a2f65607d59d072f448e274b30e696794ddded8515da1d92980d4b2feaa815090a472df62d8602515e9c494fcc775 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14618 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-remote-api_1.2.0_armhf.deb Size: 3167804 MD5sum: 276d384e42dbd0c87d545062cb2a3829 SHA1: e363d2ba1bc9b2b3cbdc14052c80a89be9437544 SHA256: 68f7e8a495f3623f36d3d7d059dc93873a64f43c0156ff99c2486ba40f9c1efd SHA512: 014bb142a8239d00a7fa7eaabbe736c5fe1e67c40fb5fe2dbc9e98b5bacf6a164f70c3476d11d270e611a0d31c2f2383ec62bc27c1afe717c8fd5c44f2612fee Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-rest Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10883 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-rest_1.2.0_amd64.deb Size: 2096276 MD5sum: a1c956732765539f403bc6dc53953b61 SHA1: a4842a417b624b11122873b82785bcfa3c3d9c35 SHA256: 6c364afa368f3b1bfbcc1d8197dd82d4534987d65e8aa398f70ec5840fc0d032 SHA512: d00a3294e114776c757f6fdba693bca97c0b8d7419561e8b563c1283c64d6823d648642b5511b28c73c0c5a721df3e2618c3ecd261a364fa93a5643f549ca0ce 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) Package: zenoh-plugin-rest Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9869 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-rest_1.2.0_arm64.deb Size: 1918040 MD5sum: 931d9bfd055b8c5128fb275c3d4eb769 SHA1: 3c7fea163790916f50177dd5556ffa83b496c943 SHA256: 7e2faaeeb147577f7f1953dfea0b855fa1e7a503858f57b82a7b810193ac27e0 SHA512: d0a4dd8008f51a307bc2b9ff2f3db2dde7b69e529fe18c79855fdfeab001133ad31108be6addccf288fb9197f404d4ad6c4cf53bd4e3667dacd9fabe7968cf08 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) Package: zenoh-plugin-rest Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8018 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-rest_1.2.0_armel.deb Size: 1793236 MD5sum: 5129fe5cb0bb172a5aecf0212a12003d SHA1: b24b3f972fdd3640384e6e49489b5245ce06d866 SHA256: e8e4768f9f211f229ebe8b0ba23d1f77d9c47137517babb3f0fbc598578ab676 SHA512: 1c5bec1dad22617e5307460a2f22191157ea51aa93781487a49655d93b6d2b8f8802274588b482bda0929928ce769876616655165fd96e18f9b296b4339fcf6a 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) Package: zenoh-plugin-rest Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7924 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-rest_1.2.0_armhf.deb Size: 1782840 MD5sum: ad400a6c3864456c30c6c25f30dd7762 SHA1: 85aef191b2e20b19359b705c579a9c5dd8f9756c SHA256: c2a2e33af427184c48b1d5f54fe62da63f883b991776662223a4391b6e5d76c7 SHA512: 28b534a5f8ef56761dbbdf0ba1fc8361c6ffff47536130b56b9621b9b0d7b59e9c29ab39f43d9bdad929a3f240a0c2afbd055aa5d3ac31654afae0cc8672d316 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) Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13382 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-ros2dds_1.2.0_amd64.deb Size: 2687100 MD5sum: 8d1047fc0617c7beca65d80a6603cb42 SHA1: e89eb87c02323cc57d58e807280869d238c6dd83 SHA256: b6ad9aa3a68a15269abf245c3f5f0b2a5428689c6161faf3c6b2fe7cf2cd2724 SHA512: 765102c67c0f583b6cc65ad437f1b6def75ac36b8f155bb026e38631371706e989e326dca1f34d8b4fbcdf68b6284eca86b009e5ca95d6e860bc4601c43981b4 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12159 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-ros2dds_1.2.0_arm64.deb Size: 2456596 MD5sum: 17861680704c570109449d468a54a4fd SHA1: 24de36ced69ff2e7e6d243833cb7dd376f1a6f8c SHA256: 58b7386d405668bfd26aa9e2183050aa527a77b28cb3811fc51770e8f8df3ceb SHA512: ae6c3832b327c7db28e6c923c60a9ccf60900164c6f57679aee31088a440a07fe54312990c1b5ceaaf0230db04a6bdf6ad033b8b2591dd86efdff4a0120d6a10 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10194 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-ros2dds_1.2.0_armel.deb Size: 2311956 MD5sum: 80ac5601cca1ea845deb7ec8931180ff SHA1: d752ea6b6ac22851eb1ca6f671800128fd4092c0 SHA256: 4fadd60ce9ee266af14380177d82c7f5a4935f42946f83009c755e7ccbd9fb21 SHA512: fd4249de71d802856456d59b9acffeea145bf92627a2ea9b1434c32cd325d295623658084586405c416b6b96f119e9ca2117acfe1139a9fa99638ae4ad0a2597 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9814 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-ros2dds_1.2.0_armhf.deb Size: 2319288 MD5sum: 0dcd8d3b077af6ae6fd83084aa932fe3 SHA1: f17327bd7495aa8c20303b31f71296d2cf7e8ef6 SHA256: f6bf0e9ec65847bae204c9e90bfad3e6eb15e95120bdce10d2972c192e4befe4 SHA512: 1b0276c0dc21659de430eb89fecdbe1f351d2fc68489f948c6a5ed2bba643eb28c5f391cffd3ee44ebaecfff9342fb82d1e4e006c9159b3b4396a13067f2f0fe 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10615 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-storage-manager_1.2.0_amd64.deb Size: 1986116 MD5sum: 299b648c2877bd6f6eecc1e1bbc6ae5c SHA1: 0bc184e1cfddae7a0ea965ef19a216d90f99b5c9 SHA256: 8ad26e48090a826336de403ecab9b189a12ec4870535496b2501de1a02f893d2 SHA512: 2a1dd29c2d89dfc1a88cb86494a8e36726337c0237e3ff49e3f7384a7941688acf6556f07fa00b745ecfa39eb30b5a83dd1487a1223648eb153e42c6e855efbd 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) Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9580 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-storage-manager_1.2.0_arm64.deb Size: 1815520 MD5sum: 4141fcdb3a5cab16e6ff555fd711bf63 SHA1: adf29aa416c5a6897ac9659071e3b3069cf0ca5a SHA256: 12edef5e2620d3c490874ac9dfcf6aa4f456f6c3e265dea97ef7246cfda4c897 SHA512: bd67aa1287f8496a73e7b87c8fc66eba1a9c45b261363dba6b15017c564cec4262832307b7e28085b17689b5f56c05a67cba81fb5d881f81b5dca783bb6ef01f 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) Package: zenoh-plugin-storage-manager Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7779 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-storage-manager_1.2.0_armel.deb Size: 1709108 MD5sum: e39118aadb25ff78749e7bd2c07f519f SHA1: c216d121390ed2c976b5a2f082802c833b442bc1 SHA256: da4fabbde1459ed8951b1920583cb7a726267506c801e9b720fead245982acc3 SHA512: e73563705d1f448fbd2aa01b522a428a867263b5ad4a6ef79cb8f617dc3192fe328ae9e44d7b32c917669164fc82fa4be12aa8d9d4404e4c94b5f2dff5231b10 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) Package: zenoh-plugin-storage-manager Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7665 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-storage-manager_1.2.0_armhf.deb Size: 1694792 MD5sum: 2601000c844411d678b5e41ec64b2693 SHA1: 8d6be1f661f43de56bad302c4c926729d1c1ac7d SHA256: fe6985bd01edc8121b0823533e5850c8f6dca878b302ee61ca1bfc26b1ac90aa SHA512: 82f603a5bdc40c2e6d3b748cc8e5b9c512f236653265b13cfa8b0a17fa121b0930c1df5970944250351cf85cc5dd51e7b3ad7a3f0d92d134f8e2a301ef8d4f34 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) Package: zenoh-plugin-webserver Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13299 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-webserver_1.2.0_amd64.deb Size: 2501440 MD5sum: b129874e6c12b57ff7d2b9ca6510e63a SHA1: 89ab74c387d2b6cda70faa65f43d432319b3a57d SHA256: d6690c4149d7e26abd0e61d3911bc7a097772dbee956fa83a6b33a9804f6a460 SHA512: adb9448177f804fd6bfb8cedfdc30f3248e0e8c53238fd6633ad650f04aaf936799489c46267a90b175ad99ef0e917342fd1032fbc5d75ac08e040e20ee22f3a 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12481 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-webserver_1.2.0_arm64.deb Size: 2331860 MD5sum: d8c2fbeb0d5ac9b914a4bb0849ac404b SHA1: 71f30e3c99b2fcb028cd8850ba5fcb081e78f542 SHA256: b674324a9496407680f11292dbaa5541a0005b47a10f31fddb79c3fd2fccce46 SHA512: 0b2a8be4ea671f27924b4958d5c953f5deafab7bed8341a8be6bbde4ac07c6c9695883bd4c1855fb621e7cbf2d81ca357dab4930c074a9396a75e6c473cdf84d 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10196 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-webserver_1.2.0_armel.deb Size: 2126916 MD5sum: 6e014b3f6c661d7b1612cd9407c799e7 SHA1: f4debbbd224aad93e4bdb251d7b9b532154b6bcf SHA256: 80d9232369de752f3709da8f636deb8b0a32bf63cbc275e2549d00c32005b420 SHA512: 11fd9d66fceb92e91b683f264b8380fc4538f99779d87d18e0116514fc569e514c465630c5053899de51e07f56d7ad35a374a206e712ee70cc089da6dccfaa60 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10059 Depends: zenohd (=1.2.0) Filename: ./1.2.0/zenoh-plugin-webserver_1.2.0_armhf.deb Size: 2114912 MD5sum: 81f444b4c5af16be5aeac26eeddca60c SHA1: 1c2f5dd7860a28f0539479a20d40a1f055464299 SHA256: 3bf898ad671f841439a712f0ad0259e82a9a65ee819b2d9a924e2f2498f64e0d SHA512: c4be41d01fbefa276f8f58ad67e3a005c0651cf545157b3ac89945e9adcb94df5bb044479d748dec5536816c31d530316dc8700e9249df56090e9cd32432cd15 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.2.0), zenoh-plugin-storage-manager (=1.2.0), zenohd (=1.2.0) Filename: ./1.2.0/zenoh_1.2.0_amd64.deb Size: 17456 MD5sum: a3f38f57eb1cd6d96e78add1fee5a035 SHA1: c2e808db54cae205029c3ff2d10e48b54dfcb666 SHA256: 86f7e9b31df59706c66a2a0df6a96646b10ad3d87b9b8795a5b409ece7020af1 SHA512: ebdf62a6772693df19bcd8fa94d1dd68bad53b06a86f43cfaddd804d279b526777d67da240af26eb431759425ce86fc7467c7a64ca44883e121c1c1512c40f3d Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.2.0), zenoh-plugin-storage-manager (=1.2.0), zenohd (=1.2.0) Filename: ./1.2.0/zenoh_1.2.0_arm64.deb Size: 17456 MD5sum: 073745e37379bcdc2c42293440d64110 SHA1: 1f9537d0e0dbc6c4859d1de5fae077f1b8332a11 SHA256: 7efda1ad2a7385adb4e4831ba45141ca9a85f35761e8af1a95913dfe09511abf SHA512: 0baed97de5a656a655e8712b8d06ca8023e99bdd115b7c139a7c294d13eeff2b1d9ee037457b9dc0117c66eed33f575adacd13fca0c9a1ae668744524d515e67 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.2.0), zenoh-plugin-storage-manager (=1.2.0), zenohd (=1.2.0) Filename: ./1.2.0/zenoh_1.2.0_armel.deb Size: 17456 MD5sum: 6be49e92140dd9f8453bca6ac3fe346f SHA1: fca0076e1c13c041aec29d3aa3d5498c9f7ca468 SHA256: 9a6dbdcc8ecc051af34bd13f5447fa3f0f634bde7cff4796e063639cd20dfc7c SHA512: 141343065d76e6b66eff3037e92a1d9f0f95e0a2f4b6bc41b4e2b8aecc767e977bf932307ce15c71c83d9995d0dc16eac961a490837be791f4b30dcc547b2c29 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.2.0), zenoh-plugin-storage-manager (=1.2.0), zenohd (=1.2.0) Filename: ./1.2.0/zenoh_1.2.0_armhf.deb Size: 17456 MD5sum: 81710e0449905cdc27749f78bb6cd301 SHA1: 03ac5ef973d8157588e33c2a81ae453f9f3b3501 SHA256: f1bbd7f4d9a3ebf5756ce46351db29df94afa6512a95e7c95d65a62a8ca73850 SHA512: 83c0d6d6bc9826f8a281367f139a618028dfeb50e326b2714f484d6f9bf085afc85356ecc3b8ded79658aba64b6a72481cdb14056b933acb487ad56416c19331 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: amd64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18456 Depends: libc6 (>= 2.29) Filename: ./1.2.0/zenohd_1.2.0_amd64.deb Size: 4506924 MD5sum: 792e94e821f305522599c544a627bdef SHA1: 80f57829558a78dda755af36ab7a9bb21eae9142 SHA256: fdaa5f2b4a09265ebf0b10b4ef42df1c1ede34cc516fe92313139b99354a23e9 SHA512: 6a340958d8d74421d9b714e1bd48c1bf596106412b5a3a5fd6a904aedfb7c8809e6f5c3dcc91ea0b4d5e0ac66d3b156f2f8d966aaec50f0bd6f890552ba8f2cf Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: arm64 Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16557 Depends: Filename: ./1.2.0/zenohd_1.2.0_arm64.deb Size: 4043120 MD5sum: d9484b325237e4e1e1aa483a07514ec5 SHA1: 5cfef5c824d3cf2fc2612e5246080bc1455ea86b SHA256: 36980ef6b243f496adc0d5e5242177e24c593a04b3b6483808232e7cdfdf6297 SHA512: 151f93ec4074e2611c662f1c6656d32dafb0d3c01e3e5c58b539cd5a8aa2b066fc6e9c2c6122c58536dc9c159e1c677b8b5937276c6fd1064492b06be4533139 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armel Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18005 Depends: Filename: ./1.2.0/zenohd_1.2.0_armel.deb Size: 4422624 MD5sum: 7c05d7a8f87cfa3343903111425852dc SHA1: 9ce626325f0de12a57213e0b1bbc2dddd6d7d73f SHA256: ba1856811c58fb3f28bab6834b6a5ae7bf6d02265a32dcc4e0f67afaa7b88545 SHA512: fc4c47b7e7c917c98e21f24467ecc18c4d1afd08a7da6fd8d5afbfaf53be1d8b9a6342d4c3c846671fc49b8f9b9e03e84f104831d763c15716161c2b51ed8ffd Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armhf Version: 1.2.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17775 Depends: Filename: ./1.2.0/zenohd_1.2.0_armhf.deb Size: 4478536 MD5sum: 5b5d8391d02072494f5419b4c4e98b29 SHA1: f751076b082b9568fd0dfbbcad2c5da02e84347c SHA256: 2f55e0e3ac0da92c51c48e2516ed9828ec7bc1987ac255f35ef3b67dcaf6d502 SHA512: 01d306b3ce68027b2ae35e6c6afaa2c491cb0c95d90947d014917f3471ead0794ac8d895150e0e34944a3ff832953b6361961c041d7e6896088649898c284d1b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: libzenohc-armv7-dev Architecture: armhf Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31027 Depends: libzenohc-armv7 (=1.2.1) Filename: ./1.2.1/libzenohc-armv7-dev_1.2.1_armhf.deb Size: 9533426 MD5sum: 1f629fda4f944a53a7639f54b0046071 SHA1: a5b6c08d5f7e74646d324a0c113fd9174b25dc23 SHA256: c45d335b7f0ca9a875326516c8118062c25a436af574039d84d49bfc0998a3ff SHA512: 313ad8e6b1792012a9d9f05b0597951050d2c75c07fa3841776ccde7da48049402895b6c267f447e53eaad2cdbfade62319a4a8aac305c9412d591929138daf2 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18432 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohc-armv7_1.2.1_armhf.deb Size: 7035638 MD5sum: b6fbd9666ab73aa7b0ae266882197cf2 SHA1: 79329526e620123eafc4a7e47fb3cd6673f77b40 SHA256: f513a47adb94e7101189bff3fc26e50b9b030af652f12dce72a720b2c2e0470f SHA512: 9cf3fabf073978bcb2b0b5291e414520e1c5ab561818f8b4e216538caf4fc998b344498a057968ca0fec69a0fcf2d46910314ad888fcca6b57c795958b377b7f Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 39161 Depends: libzenohc (=1.2.1) Filename: ./1.2.1/libzenohc-dev_1.2.1_amd64.deb Size: 9091532 MD5sum: b246f856637ea5df0535627d2a8625e2 SHA1: 4ed16cdb733adfd535e994b6fa6384a5a90fedf3 SHA256: 94412304964756f12905a5052bb38c302501aed9b0de4c79d635d25e107e8901 SHA512: 8e1aeb46ddaa6b1700e7d21a3292e08df94b24798eba084b43f2667abf034976fad255a3dd7f419a1d047cb28ca17b885ddbc552326d35c13ea18eeb385cebdb Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 39504 Depends: libzenohc (=1.2.1) Filename: ./1.2.1/libzenohc-dev_1.2.1_arm64.deb Size: 9189248 MD5sum: 85ab681e3c38003449bac9a41e3a5640 SHA1: 4a7d1732875b7c2760fa7b66f9a6f49667c18a0c SHA256: b22aa998187639a6e61130dc8ee5b26087cb75bef32fd16f8a70bd62c62354ac SHA512: f0e43d9f636a8555458b9a94f460f7597647cb1141d8ef003b68ec7782c0a75390de606c980a74047efc5d679c169206bf9385572beeb6e3bd8aaaa8bdcea51e Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31880 Depends: libzenohc (=1.2.1) Filename: ./1.2.1/libzenohc-dev_1.2.1_armel.deb Size: 9711048 MD5sum: 5b7fa0654d9468f827a8a471aca3db40 SHA1: 02e8c55d34a972404a6c94df46288ae5a25ea0b6 SHA256: a875a916a03ac5feddc8ed58c173b728975beb7d99cd269ea50eafd7d0dfa0a9 SHA512: 7c69ee816dcfdbeb18c71f3d2a84a6c206a4ab94635f8b9dde3cf9b51badfbc7b6d7c1cb670de8e10d7cf6e4d2bc4fc3a447feead4a9690b1029bd9dd2eded54 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 32047 Depends: libzenohc (=1.2.1) Filename: ./1.2.1/libzenohc-dev_1.2.1_armhf.deb Size: 9828876 MD5sum: e0bb2f3af737780de1fcb1b2b55e4dda SHA1: 641ea191aa42b38faf4b76c6e53f2b523939875d SHA256: b43563c9a8a9916a5b3b5fbf932143854789b7c5bdb2eeadbf461f1d6f2ac943 SHA512: f557179a9241691b609c4f71ec434198c3ed5a0ecb49ec24d93f2af890450f9e565167fa6438932c02116928d0f8ce994110c1db59ad3fe9a4d3e9a171ae6aec Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 35035 Depends: libzenohc-musl (=1.2.1) Filename: ./1.2.1/libzenohc-musl-dev_1.2.1_amd64.deb Size: 8852218 MD5sum: 4688a28d77e3c0006bb9aa5d0d35772a SHA1: e93eaaf09a3d5c46bfb33057800f78f0dfb3cb19 SHA256: db60fac2ba00f9f04ccba6bab52b861ea897ddda21cede7458eab6b91c3ec20c SHA512: e0524ab995d8ed639c9b500d9b6b6093002c8181a574deb97740fcd3da90717cc83fa34f52dd8cab0052a7770e8a48303367e805edae6486bc5d8d6d55258d45 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37502 Depends: libzenohc-musl (=1.2.1) Filename: ./1.2.1/libzenohc-musl-dev_1.2.1_arm64.deb Size: 8929596 MD5sum: c4597b54709260037ce79e5f5f3fcf3f SHA1: 778356ce4a96a75f67ad3183b43b4085fbbc5918 SHA256: 4106266baf1a2ab9f8829f19fb4d416accbfe482a4521c26f435f62b5817aefb SHA512: 08aac4444bb67e609769a46886280a5c8cb138909c6bfda52690caf2955dfb2c52cd4f364724bc5e80a177044ef611e587c33a3a4f89c8b3be408c32c0b5d542 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18533 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohc-musl_1.2.1_amd64.deb Size: 6717708 MD5sum: 5b21d0733b9836dc1eb7710c492cf1d4 SHA1: 5f96a6b14ccd92e5d12889f7232433edcb712f2b SHA256: f57fa91f9fe8f5cf3dddcd1a82b9d27479838bdc67419772888c130fd7a60b0b SHA512: 1ea2cb89c7cb18be013628a87a590896f1bf8958c31a2df35b20692134121f7facd0503844e6d4fa165553ba1608e7001a1b88bebb672142c044bec845958763 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17196 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohc-musl_1.2.1_arm64.deb Size: 6398942 MD5sum: 392c4f472e0b08d3a8000beac23dc85a SHA1: 047c6bf0fe7b29ec367b996e3fc4341cae2fcf78 SHA256: 99dca6efd1a22f8bcaab0958daad87270710b38dfcc04c6f86988b81a1d85a07 SHA512: 96c8adc34fca72d6daa27cc38860b321b431aea7e98a4c61e3668107e9615955a8ccf084cd62d49621cf5bd3889efd92c64a2fb24c89629b791f6efcdef92888 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 19115 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohc_1.2.1_amd64.deb Size: 6735268 MD5sum: e8bc0affb4785e31010f4c202e776332 SHA1: 5aeeaabbc65336ec2f0460467e35f028f94adb30 SHA256: ad390ecb3f0b25a0c82d0aa3af534f438ce0988a39f474ac03cf3de2005c3365 SHA512: 717e913f19e8167f92cee22db13125e2e3cc783c0e01472c3e83b1bfee70212e679464c72ce5758c25e194c489bd6ad3563fa35abef790865c9b91ac403ce4cb Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 17537 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohc_1.2.1_arm64.deb Size: 6466582 MD5sum: 4a4b8c9353c7991cfc5515acb41ea660 SHA1: c4f7130e32f6c0fcb5ac99a9588ca382ad117938 SHA256: 6eab0488c70118663b220857d221c3ab824e4d239d2c9d014a93e2575ae901ff SHA512: 6cc5841970e017bdd3cbaae6bdfd39a38b7c23fed870520945b384e02fed4ff9d31c945843f8b3a4d7383489168df4010485d8f45b5b6cef61216d0127b285e0 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18842 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohc_1.2.1_armel.deb Size: 7122400 MD5sum: 4c36c4654eae0b985b05d4f5291056e0 SHA1: c87b928be7297b258d31375e46262678495873c2 SHA256: ad8f9aa44693b0c4dc20bea34114207e930dcc02387b345f2ee6361575e4567d SHA512: e9bd795653b677687b8ea9cc9bffe3c6b7438a46e4eb0144f58b5aaede96a79c30243a8444b230811231aebbe84f55b586f25be86a97936f8c01e14c5bc18b95 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 18829 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohc_1.2.1_armhf.deb Size: 7195258 MD5sum: 0f234c086848018a053465b3a624bf3f SHA1: e0cfc51e39c8254253cf4a54921fe5494b15f61a SHA256: ac06231ac6777be5938aa65be154df292b8e1d9da7a6000e9b8a17e86e036d29 SHA512: 0a0b48a9b82ed9bf83aee78886cbba5bef95955d8ddc7398b99de36314dad2eabb87e527f8636c0ab30e47d1646ccf51bf2ccc41f651647443c65bad023f4c41 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 442 Filename: ./1.2.1/libzenohcpp-dev_1.2.1_all.deb Size: 56668 MD5sum: 2a8f455361b995843fb7688c6376c210 SHA1: 09c680519d7ce1c3b6182accedf7919dfbfd9d1c SHA256: 22cbd0a9e415c83f89b18c98cc7102fee1460498bead90018930fc78b09f3207 SHA512: be65f51dcfa482b0327dc0657eed0e9c140d66a3bf5852d9dcdc37556cdbafdb200d4a40a8d2305ec3fc488c29ee394eeac4a178b8ef8e1fff0be1da417d6d0e Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1208 Depends: libzenohpico-armv6 (=1.2.1) Filename: ./1.2.1/libzenohpico-armv6-dev_1.2.1_arm.deb Size: 241414 MD5sum: 5a4222af5f9e535a69a7d710a59369d9 SHA1: c60b63bc294a3a51eb9077564574368e38179283 SHA256: 3002307311eb0a5a8005d38a14e7e36f45d8ef386f0f00a59e295c4a465e9d6d SHA512: 89352c7734d46672f01b88e2e95aa9688c3317e42e072e87a6eaa740852db4ba7f55b98bcbd2938f69f50cd44c1ba3cd658abe77b6453b23d0c6f42906becad1 Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 349 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohpico-armv6_1.2.1_arm.deb Size: 142624 MD5sum: b4e11ae74bbbe83c613049761d528030 SHA1: bb3721d70e866138947507787e9d91424ced70df SHA256: b8e0a7163813c5e02012d7418f90ffcc1e4b0eba2ab9c9b68ac6429cde99bd5d SHA512: e1accb131e3adca2fb88bbd055a2933d014c6889265cfdadc0a11ddd82a46416d37e8fc1d1c9db7a98dc4ab15f94fd6c43a5961b8f2ffba31ef7c651e008ba53 Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1200 Depends: libzenohpico-armv7a (=1.2.1) Filename: ./1.2.1/libzenohpico-armv7a-dev_1.2.1_armhf.deb Size: 239950 MD5sum: 8fc5e764841574e5c7cd24da44cabb70 SHA1: dd2bc51f84ac2864e92de8d0d2ce18797fc2f771 SHA256: 51eb07760e9bb45340e60f7e1ebc701a2a2fd73e6786faacfb2eb0fc9c022ce8 SHA512: 20ea3427ce3845b530713ad49af78159584ab77f1220daf9f00013e35d51e907cb8bf43a5364a03450a4295ebb953b39dd71a2644bedd250fd051412950174f5 Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 345 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohpico-armv7a_1.2.1_armhf.deb Size: 142110 MD5sum: 688a1ec3dad022fab83c831a891e6265 SHA1: 5935f07fbba513156b8835c907b00a9c7ead88ea SHA256: 0747753ad8ef3642f2ab333380ba481c6ee7b8a2885c95bf99264e8ff7f2fcaa SHA512: 525d4dfe2c9d0cd75db7fdb7b9cb63593524fbb8cf0b006e0576b9625639e2e64330e9fe38857e85477743714fc0eb9b36d78b69cc733df39354701736c9014d Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1451 Depends: libzenohpico (=1.2.1) Filename: ./1.2.1/libzenohpico-dev_1.2.1_amd64.deb Size: 287642 MD5sum: f11b69f813459bd53991d22d1fff88d7 SHA1: 0263b4ac7e9e1f94cbdbd8f3cd3999eba95ee986 SHA256: 7555f75e05a60a9f569752f8f8373d26ad3de9372eb76d018a5a089f4a49bfb8 SHA512: eb532d51c984b9519488bb95e631ad52b125e8ff06e7caf17efebebd7f54a11a483db0e7f2288226605099331dfcb67b558d9716612243ca66b4684be5bf6376 Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1207 Depends: libzenohpico (=1.2.1) Filename: ./1.2.1/libzenohpico-dev_1.2.1_arm.deb Size: 241060 MD5sum: a191e04cb019bda4ed41b060add98389 SHA1: 0eda152bbd9e42ac9ffd780d1b888645006ec38c SHA256: 7eb3ce2cbcd5db98c1809f5bdcb26ba30b1db55ecf22bb960772f4754b23fc21 SHA512: ebdda338a43ec84b03553136bc8a25e31830df0cae45a32229040862b4f89cd8f876e3b1328dcff085ae3c7de8685f8b190ecc5d793299c8d0ebf746536855e4 Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1462 Depends: libzenohpico (=1.2.1) Filename: ./1.2.1/libzenohpico-dev_1.2.1_arm64.deb Size: 284140 MD5sum: 4723d9a3f3c580a2bf89a060e4f105d2 SHA1: 6c845fd4e6f2d0cc5170c51b28d4b9edacbe7341 SHA256: 513337dcfba1e53ab30e6012fd67aadf3dd7da3f4fdbb65f5af67af81e7aedf5 SHA512: aaf9e91b1d03241991293fd813c584e824e5dc880d2dfb39da994999e1188cc0498e1647baf665de6e5cbcda60bb0b4706dff85c1b720175bff3b42ad85765a2 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1201 Depends: libzenohpico (=1.2.1) Filename: ./1.2.1/libzenohpico-dev_1.2.1_armhf.deb Size: 239656 MD5sum: 4552e7ed795d7ba2f3da98876bd5781f SHA1: f71b5c55e9e288016b8f59dd3989599a9c076228 SHA256: 20e79a33b59aed46d07e05f004c7cd2ded752cc8b7c99d099c14a22a9051a229 SHA512: a34a03a96a15313b4e771da37b27d72bb5829c280de2c8208145cf6bab5c8341d6fb798bb1d2f01aa875413d0be37e684fa84089cdde6a66e7b7d414efec1455 Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1421 Depends: libzenohpico (=1.2.1) Filename: ./1.2.1/libzenohpico-dev_1.2.1_i386.deb Size: 312152 MD5sum: eaaa74ad3c7cdfd694ae8981be7901ec SHA1: 627da2277a8b9f0ecea165683cfdc5084a67722f SHA256: 3aa42e89d7193b767cdc06c44752209924a8527f04348315801a71da013d131c SHA512: cb74bb3430c395dc78491cd3f614673c0f75e1c206eed218af3ea78c95b74f012eb81ac0a942d44b50e69ccad9be317de46b9aa292c3aabd1efe7a87f0a48571 Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1351 Depends: libzenohpico (=1.2.1) Filename: ./1.2.1/libzenohpico-dev_1.2.1_mips.deb Size: 271786 MD5sum: b323079b4b5915e6fd00913aca5fb6ad SHA1: 5a450288fbfeebabed620083a466f50bb1c02110 SHA256: 9179595e4598084e709f72034ae5f18616176231fc24be421a2b1d96c7020789 SHA512: 74c5258c65e20311dc5421e0d90477b5c63ff8c07889b9d98ec90ced126c14f5698c35c7f7164b27768bfec1aee0fc8ccc4c275fa96e91f6b3d556f9705905c7 Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 472 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohpico_1.2.1_amd64.deb Size: 173830 MD5sum: 02038fdee9d514f904896bdfb0cdf190 SHA1: aa33c90073fa42555f1de892fc2e0daa21f41038 SHA256: 3ce4216c5e3acefd31ba4f7a3a84c480588c307898c05507e77ad2a81d65be71 SHA512: dd4cb5b3427919e8d2ec243e2ee95efc846c4ad6b89b32b91995533ec32b5c6793ecf23f4cef6eedb01d43f34c44dbd9944911c2c6999b939d7ffd5acb77509f Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 376 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohpico_1.2.1_arm.deb Size: 150904 MD5sum: cba0cdb1d90aa85a262894f378fb13d0 SHA1: 5846c8998489eaab0bb5185a19890ad3758a15a9 SHA256: 7f613ccaa935e371f449f11b181a85a7e2642b4fedaebf3390429cd774268ec3 SHA512: 6dcdbebbcfda160279879bd991820d04f1345ae1c0ed50f743e3eaa061c28fd643afd5ee9359b43ac7aa596005bba6097f206b661366c47b6a3888e4981687a0 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 486 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohpico_1.2.1_arm64.deb Size: 172032 MD5sum: 8346efbb87296ad93d50a3e126c1a274 SHA1: 2d4a7bf435e3ae338e8d807c661722f01ceab6ba SHA256: 747a688cd5766be2b733b35b7a8a0b27058e870a0e7793d79fc2957629d862ca SHA512: 337c32bb6c60ca49fe6635730a34e751826806a3e3ad7e0e4d11b722fd0fbcea0edc39f89d2f34a2d22b296487d7113ac7fd81cec0c1cb3dac6557e23569ad03 Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 347 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohpico_1.2.1_armhf.deb Size: 143142 MD5sum: d3e5ec1d51e21c6f89f348c3ba64ab71 SHA1: 30a6123640216ff9a56bf1d170b73ab7cf22c508 SHA256: 6c03e32c7d61b49fb944350101174558dcc9fff45dce66d5ef707dafbd84917d SHA512: eec454ef818c468acbd10be7652db80263ed55a3cc8bdfbc6e18e28f5209d170eacc07621969ed829e49935d61b8e2f78384e4bac29085918837d20047b84100 Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 503 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohpico_1.2.1_i386.deb Size: 197460 MD5sum: c68ef3ec9e4acf9f2750bd0397d9d310 SHA1: aa70f6fc391b38dbc57f889ec357c0c777877bd7 SHA256: 909082eb8a1c79559b63f9d26c9a34a22ea9e5bc2da560ceff6dfef7da2a7095 SHA512: 78014169c2fb2edbe74f61cc0562146c654d6c5538818cf2115be09288ed62ab4a57cb89f778341e3f9a8ee44bf44f42d5c22b8beec69c71105b23fd6e718edb Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.2.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 453 Depends: libc6 (>=2.12) Filename: ./1.2.1/libzenohpico_1.2.1_mips.deb Size: 155930 MD5sum: 385fad18e7322610f69f74653c4a3e86 SHA1: b2d56376188c60116888b3e094d343507a52e827 SHA256: 06841c4b59381d822b6e4e98a21ee45eab61283903f523be34594c2dc8e06a52 SHA512: 49e7c694483e3a72f086716d4bf2ce0a9a1329b66ac50740b65cb971c90bee8df6a0c1ebe0f0a50f03c6574727f4b29b11f0a907bf8bfdaf068844f7f1d817d3 Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21693 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-filesystem_1.2.1_amd64.deb Size: 4779316 MD5sum: 50b78a0678420cddcd3c230557685c23 SHA1: 1e581a13c78c9e416dd387c6732ce8c0091eb7b6 SHA256: 9f3bdfa1d2ebb27e29ae11213c3047cedf5b1b1a4c2ddf48033a6a5d5d0eab09 SHA512: 3d760d193363d8df6825cf0cf2f8ebaa0cc5a64490ec588d383082edec154b298fead211ccbb564a2dea388e3bd4772e4a144a423d73102209871f6c4dccd503 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19741 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-filesystem_1.2.1_arm64.deb Size: 4281412 MD5sum: 13dbc91573ae6f520c247a03f768129d SHA1: 491a14ce49b3cb8ab6803454cd6103cd83631f78 SHA256: 51558b6f03e8bb0fd5c03c47fbb6be1f7ae70390a04df0b21e93973508e43c56 SHA512: 13cedb83c2f4eb7364251d5b1e4b6f830332f47b4d17911c2c4f4fe84511b10baf30f37425ed9089e2f173b4811a7e960b04ac4bc3db7a795024516e20992594 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17316 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-filesystem_1.2.1_armel.deb Size: 4058860 MD5sum: 30d29aa773f5c860935a0c639687d80b SHA1: cdd380716dee057f45a5822d357fcd0a964ac442 SHA256: 7516b9e31c843498ec388c992c97e7ccad106928ee29c63d11860f314551aa3f SHA512: 7a2abeb70d14d5394cf7e1d82f996a1e5d0d2bae711ee816ae536e93005b2ac916030df6287b9363d513da12d5c15da274f779417254d4484ca9ea15272d1812 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15232 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-filesystem_1.2.1_armhf.deb Size: 4164200 MD5sum: c33ada0ab52db387a7d56c87ed8cd14d SHA1: 6c96c513d9de4165d65648afdae968ece48d1246 SHA256: 41cc3eac024b48fea8a0fb1acf1af17f6338859f31f2b76a0ad3cfb56b895bf0 SHA512: 7b36ee01a559cc60989eb5617a56d4b900351cc5e0a01f666ded26997a51dd7be7517facc235eddac82a11aa951de98f4ba51dfb720515ccda1d1099a6f62d2f 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15712 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-influxdb-v1_1.2.1_amd64.deb Size: 3129728 MD5sum: 5c2fc770d4ec76e4abe1daf65cfe9f43 SHA1: 76f0b775c3da9c826394fde37c8aab53524ffdfd SHA256: 0187bed717f7a0e5079e71ed1c02e6dcec9aa73e1b88fd6795464687c6040f9e SHA512: 1de2f6ac460dcfd78dbb6a68ec2c9cf3ec2bf54c39b991de9940b7513da9ce76041aa717f5c3b5bd817ba94c69f766ce2d7d0e29f2825bccbb53ed4ebec2d697 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14034 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-influxdb-v1_1.2.1_arm64.deb Size: 2813396 MD5sum: 1e2720f74ab1d5b336ed379d7c3d54ef SHA1: 16436e517264d776e6754f9fbc2317dc1629e4ee SHA256: 16e4d3c9ec06174166de09672eb01b0b306e8c7e7fb09db9d018796963852be6 SHA512: 15e072efff96d4bfebe3dc4ae151d17c305833696c565adfd193789168205c32e84a1b7e600a679393ce74e91a73d1b554bc97fadcb84eb27fc3429a7ff46d19 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11807 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-influxdb-v1_1.2.1_armel.deb Size: 2552292 MD5sum: ebc12838a2d27be9ef9d4fdef3616ac6 SHA1: 9eeb1c57aa55c65e6ec52467e9b7e1fe395233af SHA256: 33ef0ca00e662743a148a4c1335a9244bce602c8f366e6410034a8eee44c669f SHA512: bcdd7e0d4ac23469a500fb46afb28bed2f8e3b413ecaf3533796a0a65c29b43bf4d89325bd7f3435dbb26da81e029b8b2eb752fd067f61fbf6b9c93cb05e0dad 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11683 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-influxdb-v1_1.2.1_armhf.deb Size: 2543428 MD5sum: 6c37d1bebd57fdb7abe005f5b91e70d5 SHA1: 45fd7cb71c580aa0c60f639284aa46b76c6ee6e4 SHA256: 0e9643419f7392dacdb27c028e5b859f99e2b0f99f53606fd15cb5cebf759692 SHA512: a56ddec6db41309b1ab6f13094995485488769025524f27c93a62d8535f2bcfcf0a33b1f0f90af58977c9a59fe9ca47a72f8939e77c53f6976c1c8c0e2327100 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17315 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-influxdb-v2_1.2.1_amd64.deb Size: 3806008 MD5sum: fb0fa3f2070ba5ad30461be16166ef2c SHA1: e42ca01f0436020ea5edf595645288517f9be5d0 SHA256: 734cfc80e2be86a5ea0e05ecfa3c0557fbfcd863c2d13302979ef064ccfcde6b SHA512: e8d77423236bff885fd022eb3fa7b00d3406df7309860de370a8601d9aff957173d1cb39654967ca55b6f4a741a19f5c9ca981398bc271c0e876dd4c11e63c2f 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16302 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-influxdb-v2_1.2.1_arm64.deb Size: 3488688 MD5sum: 8c70d96f3f382dfab694819d0ebe46cc SHA1: 81f33fc25710ed847c36fa83a7119814145c367e SHA256: fe3dc1e93b877c986e558dd54dbcb24addcb8254e87b8fc831944c2abc34fa10 SHA512: 916f53be23fb5253cf262372ec6c2dbe1ee7ae343d2ff8c5eef45a8acc2d43e50e792e2c1c7e7954b2ab028597e076a8950d0e24fb4dd0710650d47fa7f2a98a 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15590 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-influxdb-v2_1.2.1_armel.deb Size: 3470472 MD5sum: 156b89730b8c305d9e84a0e6a0f5bff8 SHA1: 365d526b181094da19b5a6c43d2aa8f1b741f571 SHA256: 1582d4a38408d908402c9aea8602ea4da6f5bed850bc0dec83a970c4f864e513 SHA512: 2d877c6caaadf973b00cfc828aaebd0c0a655cce8937b8eeb02267109674b81245e91923f65a570391da01cc57b74b398c1b7918491deb857f4042d8af7dbe1d 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15485 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-influxdb-v2_1.2.1_armhf.deb Size: 3510976 MD5sum: f16f59bd30b6dc87c34870f2b936e3c9 SHA1: 450e408af461026d08a6635e95ca111b2bbb5c13 SHA256: d495f09b8831d689e390e49105998ead6f8afc842243c2a9b5e7132116e9cc44 SHA512: ae377ea6d3fbd3c390f34b09ecd49d6d5c458d959b413b22bab99591132a7f411660b3fa6b79ec7467c08f2a086baae9b58ac9c2bbdd953818e3bf3eee3bf687 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20233 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-rocksdb_1.2.1_amd64.deb Size: 4504364 MD5sum: e22187af6ba6dc47dc8b09b35d4418b3 SHA1: ef6eb99827527d71473d0b01c41042db79929993 SHA256: e2c1a2a1b14f2391f7c711dc4eefbf13bf627f43f444d7aa3445c5becc02866a SHA512: 877ab7937886aa676b29dbcf5e38c656ca4630cdb863afc5e65c72f74ec9a74a43134dbf9a45f4f4a1612ee75341afa0028dd84791d76291b90a687599dade98 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18294 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-rocksdb_1.2.1_arm64.deb Size: 4030324 MD5sum: 27e2fb1810d75a02a06105214d826dd6 SHA1: c1791cd20e0027c29bf999cd88710d1d9a95a029 SHA256: eba3c2694cdec99160d2cc993c0175749114e068c5c8923462ae50e2a0f076d8 SHA512: e6b0634ce0dc0a8885f7733dadf2f157500f3ea5edf7ba1df666616d9458c32abc73895c04c57df38a8a6cd2539984e8d00d68ca305bb8a15f90e3e24cdf4f7e 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16097 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-rocksdb_1.2.1_armel.deb Size: 3835932 MD5sum: 32cbfe7b58cecbee68b8cc28793132fe SHA1: a459d433cbafb0eb9b3880d9935460e8368c42ca SHA256: 60764020f69627f71ee0f72e72b8ba36ad6afe264a2cd8607528117dc873e9fc SHA512: 0e765023c5364999dbf7c4015d79172d744c2287a26378f50d71110d03c84c93a9afa5a3acfab313fc05f214145ef0a68ca300a9e795b173a1dabfa3f6a34cfd 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13990 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-rocksdb_1.2.1_armhf.deb Size: 3948536 MD5sum: 0f4cad0fc7b9789b02a9ce3a901d9b28 SHA1: b4576c359170372ce4c7516e46a8424f39118b57 SHA256: 2225c74080d840060261e825bc40919a2db002711997f88371cb422eec81f096 SHA512: d1ca96aeec59eecb501d093e171c0c5890d984107fca0aed543679abc796f54a6be3b806fefcad8ebd15efa6afa77f55f049ffa868abc0f6cbe0728a8621ab5e 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 27307 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-s3_1.2.1_amd64.deb Size: 5519236 MD5sum: 5f543cad81e5c04ad58f2b4e4abf2b9c SHA1: 31b39e1913cc4f190b6f5c773b9390379465adf0 SHA256: 13ef1e23a18ef86beeadea34f03acd975e030da884e4af6fc2e3032b23021587 SHA512: 6def42bdceed637582afb32f75152af39ec0a3998ab680e42a1b4606996e85e1ca22f9c280683ac1b361134793e167265a9be1a864846637e0776d5ad5ad7c7e 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 26564 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-s3_1.2.1_arm64.deb Size: 5238220 MD5sum: ef18a1a8e0558784819d277b4d66b8d0 SHA1: 7c24862c6bb13cda2d200434dc9ac0b5e7153b2d SHA256: 655ab95c84d3a22a06fe34a39908be72d25b4426fee99dea8fc15447a386c64b SHA512: 9e2bd8d9b9f6a85a8db72818e7a3409dd3c46e37065d0a520081c07d4ffd81259305fdd73a4983275ac5ecd6486dbed68178116801da9069583cdb05c536069e 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 25187 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-s3_1.2.1_armel.deb Size: 5098752 MD5sum: fa46d8229884c0bde66f3c3d0f5107cd SHA1: 8f607d83936bc55de6ca207edebb2ea1909d0949 SHA256: bc05459bb580ab0b469a489717d257b7aeda4617de1646d536d0ab3ecd6e149b SHA512: 98b80ad77f41109bb84fa7ab263e6f5253ad01445b7175d689724893c15f1816f9bf94bd9574aeabfe00ef2742dc5620c7a1be3c7580a3d932cf4807473b23b6 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 24962 Depends: zenoh-plugin-storage-manager (=1.2.1) Filename: ./1.2.1/zenoh-backend-s3_1.2.1_armhf.deb Size: 5141416 MD5sum: 05ba2904e47f807c7eb9d527450e3fd5 SHA1: cbff0425f36ca1cd2c87fb22ce6b98917d454638 SHA256: e7f92ce347cee876a14d93b2861b2702fed29bacad70d151bcb46f2bf9d26ac0 SHA512: 44f99db06ae00eea7e1c60fb8561de5ef8f438eaf8d82d96d7230a3e659983e1dfb51135238bdbf154a35001f512661b2dce24825d85dbda0864f8d8efd2e730 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-bridge-dds Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20941 Depends: libc6 (>= 2.29) Filename: ./1.2.1/zenoh-bridge-dds_1.2.1_amd64.deb Size: 5353304 MD5sum: 645a8376dc8f9aa4f8892583674ad042 SHA1: e0d94117164c6b1989a6291f3c1c1c25abe7dceb SHA256: d32959e319dec3eaf47ceea37ab4d4c49f680ef2de4e0679f2823bf7c45f741b SHA512: 3e5caf657e5bdd104a973db24fb995427da0aebb6243d96132873a90cda8ab394740c3e08084a06294f776ae838f29a49f365541cd0a7cd9d83359735e71c670 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19127 Depends: Filename: ./1.2.1/zenoh-bridge-dds_1.2.1_arm64.deb Size: 4834176 MD5sum: 7e5acff7a4a8284730b03a0e16cc834f SHA1: bae7db4267ce7366dfa91c42c0ca494f990cc171 SHA256: ccab77342d4b85f8fb5ace5da731ee9e72dfee1222af6f7d8629376185ad9453 SHA512: ac4d54022fb5fb3771b046f3f6a1d203cfa6a90c0bd237d39d0994bf7407ec59ad48a9815c5081c5a131f90f5d60a9da79bf37a00ace7c0882e69b7bfb65941a Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20376 Depends: Filename: ./1.2.1/zenoh-bridge-dds_1.2.1_armel.deb Size: 5127532 MD5sum: e1ed469679602ceafb7fe3abf6079749 SHA1: 0ca21db10b7684c90b9e5a1cfe4b1915ce9d1946 SHA256: e32184c6670424bf27e7455ced8bf1522f41dc8ca816b58785dae4799bcda4ea SHA512: 385df946d8e07a8125bf1c8982f4dd1b2c5c99c02385e52b9df468b4030a71b277e80c37f0b6e75f8b504b6b722e281ba97e9ced277556e797817e4639c35e53 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19846 Depends: Filename: ./1.2.1/zenoh-bridge-dds_1.2.1_armhf.deb Size: 5181428 MD5sum: 2796a2c76c17d7470bda810ab37855ae SHA1: 0707298e374fb36291e988aa13d090a3bc42ca28 SHA256: bcca08567e1da96ae87861e2235e82b22c74ae83c3ab54d18a5788cae241220b SHA512: c32177e35118d02dc8c689a67ca45157f225e3822e6dbda184a4f0b5f473507513290a6522fe22fad0a2fbb60e15e4327d52041bf389ea385a30ae33f1a900d5 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-mqtt Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21306 Depends: libc6 (>= 2.29) Filename: ./1.2.1/zenoh-bridge-mqtt_1.2.1_amd64.deb Size: 5048844 MD5sum: 95610d6976f2c6cbb7c46176b2a1b714 SHA1: 857eb3acda1385ddb05e1e495948c457e233eea2 SHA256: ad71f97eff71617a690f65f82d00f0713129171f911baac3bf9f641073ea86e3 SHA512: 91a563a10b651b50b8f64803db09f981d1b83b172d2f62dc9349cf7a5747c556c3af64173b8fe0f717261731a77bfe8207f6d48b21e8b6008fade9a5782cc31e Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19505 Depends: Filename: ./1.2.1/zenoh-bridge-mqtt_1.2.1_arm64.deb Size: 4566472 MD5sum: 477505716a2d2edde427f9e3412f0724 SHA1: 24220fdb70f0c53c8067b4a66c8bfe437e136f56 SHA256: b72fa4c1afef064743512d62ce5baa3387826725340fb0f2ced04c37441e061c SHA512: 09bae8f04a4e12022497a4b1d12f0a4a6307d301b4b2835c641fe0c64f40fdb0997f974418e503b1cf0d05a0b2a9b4b597a0c8a167bac57b41a53a80d78e1a7c Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20769 Depends: Filename: ./1.2.1/zenoh-bridge-mqtt_1.2.1_armel.deb Size: 4866396 MD5sum: 8e9da8d243e8f7131da678295c76249f SHA1: bf3a077b1f126fecc90c0e5a2146eb9762997169 SHA256: cb2446f5bd9492a5f403cc730b281d411195555b29d475cbd6f4464b80f8a123 SHA512: 49c7da9b5b86450b9556dd345721734c8aa751914778fe8088c525f865772cafd6cea2a7689df1bb3a50a973f79c09f7221810fa02c9dc27461c704f74811144 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20478 Depends: Filename: ./1.2.1/zenoh-bridge-mqtt_1.2.1_armhf.deb Size: 4895368 MD5sum: ddc9dd4892c8e5066cee6596c33bc226 SHA1: 2362ac3f353610964dba15a7126612cd2cf14175 SHA256: aa8ef64758a8dfd85257e223d387d4d8774cbd99cb723809293b8ea464de08e6 SHA512: d89f051e67e4691b896e240e8606114edab4eac84b174240e3141145fc0c5cfe434ef64460f58f1bc9ef9da6c69be5d2638f8f18166d414b6567691e948419bb Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 21549 Depends: libc6 (>= 2.29) Filename: ./1.2.1/zenoh-bridge-ros2dds_1.2.1_amd64.deb Size: 5468180 MD5sum: 49e21aeffed901f138b7e9a8424bd890 SHA1: 99b7d1a12dc08bbc3e982180b106603fd7293042 SHA256: db3defde5898ec426d43740183ad223006e3c2a8bce05e37d99ae92ec2c0120a SHA512: 39e2fe175f54f714070eeeef90e3fc4c4c8113108c4063b43e073ed7f7c55b9f872cf1b51661a7cf3ebcaa05b2c8d4f8f7aaf2aee78a1047ce7cbfe9d00df3c1 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 19707 Depends: Filename: ./1.2.1/zenoh-bridge-ros2dds_1.2.1_arm64.deb Size: 4957664 MD5sum: d00f9f2a1a00a0656234da30167fcb06 SHA1: dc12fc870fd5c28f311ce9c2df9ee590544b4a1b SHA256: e48a92d511ddcd0532a83cd9ea615e037321cde8ed2ea3c4a54a1ae18b9db03f SHA512: 3391abc75f618957bac4e06d18a7eacddbb1b283451a446c7d1da620bcc419732edbcc9976b1a47642b8cb1d4305948735b8091edc82db7c91fca5cb3e38065b Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20959 Depends: Filename: ./1.2.1/zenoh-bridge-ros2dds_1.2.1_armel.deb Size: 5251656 MD5sum: 27595f19069ef1395643553cd92737e6 SHA1: 0d09fe25f55a70dcd3e714f472f51a9dab3b71a9 SHA256: 158026c3512fc1552d6d184fb9038a5ac36d239f558288ac224e3ee02cc491ac SHA512: 86a06d1e9cd7a9320ab3cc3511e68abee69f26dc25e0b54bbd11c5ae60475ba649c717f236752eb6810efb1e5ed643fb45074e7f987d01fc6090881f7dbb125c Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20432 Depends: Filename: ./1.2.1/zenoh-bridge-ros2dds_1.2.1_armhf.deb Size: 5304860 MD5sum: fd9e7e41cba421a5737806f73d1396f9 SHA1: 76519ca8c7dd9c9f4382a0c2503d4e1aa862af58 SHA256: 183ad862f136c9ce5ea47d350fdd56baddb55886ec7db531d8c5b899d71c9ee8 SHA512: 1ac3ec0261475fb63b211708d56905a0638bac5949a3313a34af8588f96663f97077099bae328d0c17f69be5fd444c92015f6c4fe18d8cb05542cbd7e5f420f5 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-plugin-dds Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12776 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-dds_1.2.1_amd64.deb Size: 2578328 MD5sum: 4df1cfb5aa982506907f3ef0ba8156dc SHA1: 45e89fe5bc19fad38778b242f9fd835ee5fe5d24 SHA256: c557704aa370f4e534f505c619b21ae143d013b2fac8a3b34c55a07e10e69092 SHA512: a51575b24ee339a4ab859581b70bf042d387355c8c733257e9831354b7e8a68f5bd0331b461673f7b0bc5c8e432ac3788ac3502e6baea69ffc1a0411608cfe1b 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11596 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-dds_1.2.1_arm64.deb Size: 2349812 MD5sum: d6b79de9b910f2789d528eeac3b20e9b SHA1: 56fa76a0f435c32ec04a494d9b9530cb453b8c84 SHA256: 1f781b48c7b4e62f38bd0c95f313bed79f8f0f266454b1da5f6c5683db045be8 SHA512: fba1078d26fa5122961437302cb5d571b0c3076b48968eb63cdcd52e168632f82f0ff76f47fd7d874c5111eb7b838224a02680280e8e0b664315e4c8f9d3d457 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9626 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-dds_1.2.1_armel.deb Size: 2194896 MD5sum: ef510ca70ef37d27e1dac7d3329ec684 SHA1: 217ac07928d44c7ba34cd1eedfef59bc49774e5b SHA256: 1234e9d1a814dcdd2b3e5fa32350ba1179bae7a6e4c354ce18b32bf445c1098c SHA512: 8e45f65d231ac6d4ac61e59e26a655cf1e7fcb06c9ce1a476ec94fe896e01563b3a839d77e2cd5ccdecc5c1cf27b98ba1eab35e633605cdb3160e9605d0a32d0 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9241 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-dds_1.2.1_armhf.deb Size: 2202844 MD5sum: 03bddab2f6d560bbe031612dff609015 SHA1: 783045979be57d9a19b361c5f1436109b23c6095 SHA256: dab5d42198624c05f033b33149bcb27feeb1f31fe5c1820c75cf634ae8c76589 SHA512: a34332f7e1a9909537e63c282932f96cccd49bad49bf3ad0c0a9debe5e947fd3091dc01eb88cc083c2fd9bb76572141c0fff8cc375d0d063f4dda29885230088 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-mqtt Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14110 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-mqtt_1.2.1_amd64.deb Size: 2892644 MD5sum: 8a7d57244e999bad78361ab5806e7093 SHA1: 89e6040327a300bc5bf2bcc94cb80c3ea239fcf8 SHA256: 13f0c150604ecb8588035318f6ec126f8e6df91fedb533cdf6cc6102f59f1d1c SHA512: 332be0ec5175f1fd5fb8989a091028ec4d3508544abdbfaf9aac6dd9273951df0153480db00a19aac2547a4414d4cc15c547b8e61bd1125dc2fe66e2e6536238 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12833 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-mqtt_1.2.1_arm64.deb Size: 2589316 MD5sum: c3e4b8939fe28713cf073911635eb543 SHA1: f8ff8e1c947fa55b08e293a3c9a53a5a1aa938ce SHA256: 4f97abbff746ca2cc548eb43a2ea21c8d620cccf3fdbe720321f0b41c34b7c1a SHA512: 521440be9390be8b205e9e1417f22d798b0c5750117d7bdf571723415b66e8e643470faf3cc8634a35d323e03155dca652b4e0136ab60096648370d2451fb90b 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12836 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-mqtt_1.2.1_armel.deb Size: 2654832 MD5sum: 073fa3af5f1537b08773e094824dbc92 SHA1: d1f1736e1576149d04d7e457182e5c7d8928dc80 SHA256: 5e9ab816d8ff1c778c3ed019ea378fd77e97e59fd98de3a0c5044028452ba553 SHA512: 12e833acc26311630628669a1956ad12c29693385ed93406aab90a5f537844ee47bb6f95640e9e9722351cfe998dae57cae6adc21c3f3e6006277ad42e66d516 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12749 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-mqtt_1.2.1_armhf.deb Size: 2697016 MD5sum: 38548832fa24951cc23f2d868a66ea8f SHA1: 34c0e1c5df86a27bf00e3e56bb8319c15ee06d57 SHA256: 49a6c6f8efb1067e1c05a3e2681a0d13b64595af85c913448f1890b7413f1a1a SHA512: d84a873a5c44b04044d7d229127fb775cbced45831fbb3ef619b89cafa85175510f17140a055308fbf98214f6a18f3706f5d3cf26edb501c7da5d25a24f81bb5 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: . ```raw 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/](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](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. Package: zenoh-plugin-remote-api Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16289 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-remote-api_1.2.1_amd64.deb Size: 3465688 MD5sum: 6bb8ca44247068dbd205e2b275a6f18b SHA1: a1c9c75f634f1b7a4e8b3fe0cf5a09c68b6d898b SHA256: 9d7a5ece6c98c2404b6f91bbb1627d32a5870a7b7ba33d0bf1b068f8331f91ad SHA512: 5001b0fe8ce55614d868e1a6b267466e965c3ec215b3675034424f7824eeaf4a7a700f0a87638f353a6500fdf2dba8b5577d7278bedd1a2b8bb69789951a7137 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15304 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-remote-api_1.2.1_arm64.deb Size: 3162760 MD5sum: 9ceeec783b7249a19435458e376c5551 SHA1: 2214546cb199e3cb0a1f28dff1214f53f2a3bbd4 SHA256: bd1c1c8507dbe0bd9e100bbfe2c9a9d88049a8a1e6bea857ab8b7ab97261f6f9 SHA512: 1930209ee3ffdc8bfc6607d056ab7c229699694b02d29442305cf23573f29882b108d7024ded363f7e9952fe3f61b9f0ed0527c6b40e8ccaf51ab71f475d1c85 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14738 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-remote-api_1.2.1_armel.deb Size: 3128076 MD5sum: b1f3a017a2c5950eb5ff057c54cad78c SHA1: 8a9039e3d4c0ab9d2dead6296a029d189cef1bbf SHA256: 690862d15cf9f379efa9bbf0c67a91bdf152109774d55483189bf157eb611f15 SHA512: 74dd44783bc0ea6de6fe930cd8c9291a3518f43e79d62177e03f116a26cdcb403cb67d1c8c974d685f5c9413fcc540c73530395b21b05780fbb376734b62daba Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14619 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-remote-api_1.2.1_armhf.deb Size: 3166704 MD5sum: d05df43f8d7831222a4e156ed9dde31e SHA1: 28853dfa21b3c5633920c80011a27a61119aff32 SHA256: 63579c4d228ca5dd23e60130dc213d800e1447da142406743460c9108b7e6dea SHA512: c1c83f39ac74da5a36c1f11c851623576f932e337cc364674b3bb6e4712909573834f4e66e5fc9f8954a7a3ae6ffece4914bc76d5b8d69501963ba453027cfc6 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-rest Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10883 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-rest_1.2.1_amd64.deb Size: 2094648 MD5sum: 653ebc432086dc0d1a49b65032b89dc4 SHA1: 89525d2eac69f45abe4357889af65f8047fabbe6 SHA256: 7b13e2661e5b9cb4b332f2de6a9365181f0def5a06247b5b49c77492e421dabd SHA512: fdc866f9c981ebab1c9ed0350878349e88b5f71e95e01673ad5592bfbff3b88aee312d198d4abd54bc5c7fd97683e976caa08d7bdb14306457ef3ddcaf95dbd1 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) Package: zenoh-plugin-rest Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9869 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-rest_1.2.1_arm64.deb Size: 1920168 MD5sum: a9806400c0c39c0b11fcc2538dbc72d0 SHA1: 45b0a650df1f63dacf2fc4f41bfee729cba81e9b SHA256: ca550a171971e287b28bd7c5eb819a31145549aeb5cd718b273152b39fd0a0ae SHA512: 15975359112902d0a57ec2a087a8eff151d5e7e51020870e0873cec6757c634f50e9abacf1e769683059eb2dfb02cb66ff5f64657f95335447673138b24d42d1 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) Package: zenoh-plugin-rest Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8018 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-rest_1.2.1_armel.deb Size: 1793768 MD5sum: d9d265bb012aa444063c5cec1c207ec4 SHA1: fa84a0163a4b9021069f6507497e9021ffbb0302 SHA256: 1aae989745117a054c1ae85bae05e79a712d4293e400d842b85f83c41810c53f SHA512: aabba13c14701d010821b8210ebd9399a48c22fc4c424527e9a09dbac15bdf002ac2029dadef89dadf0ac0b0c56a2029cddbf450b6a391fb14ed27b75d17a29d 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) Package: zenoh-plugin-rest Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7924 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-rest_1.2.1_armhf.deb Size: 1782840 MD5sum: b6c01148aac33a724f8919caa12a1c21 SHA1: 2ebc324c7d0d21742bbd7679a6bef52daed6ff3b SHA256: 527e52ab33e562b8120f3a6c411c39d3fd8b4a98a99ea61cce8eb03635696e5f SHA512: de8f15135416c81189c2a07dc0bc30bc41e57591a6a4738c12c125cfffce446e199336608eca26f0bf07a90f45c1af0e1496dabf2c344ba1f8e36a1477738122 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) Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13364 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-ros2dds_1.2.1_amd64.deb Size: 2681628 MD5sum: b48c76883442c6a8a3e36f341171a961 SHA1: f59b51e63c5e531335263be1c50edf2129623dc4 SHA256: 59fe6f867b03c0d0620e43c36bd824a87eed74b96e119ea212f4d266ed063edc SHA512: 8011255417e9eb4e58f2db54dcdc09ffb83c4d57f158c2118651ba36361e8d113c8d8a4984570d3c6d96d9fa72d3635c8d9db8cc6f8720195cb133bba074b35b 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12147 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-ros2dds_1.2.1_arm64.deb Size: 2450104 MD5sum: 4f9f3b9eeb671a1782941fffd46f77a7 SHA1: ec39402638430300a80a33e0b8ca2dd0f8ced8b7 SHA256: 43e4394de054334851c9b26f78cd96375b7716613b3f61781d6b638014c08292 SHA512: 5aa288326541150243d4a93c2be9c3a6820ad4cb5509efc6644713d2d584e7781f5bdfefbb8c7288ffea688d7754a3a4f2f72314f81d98809ae44cefb6e638b7 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10183 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-ros2dds_1.2.1_armel.deb Size: 2306308 MD5sum: ad9e784f1105ab0d98ed20b5f82dafc6 SHA1: 76a5f61b32c646aaed658c55019d1c955b29842e SHA256: aa6a620dae15db105559dedf0ca0042cb0ee4dcfeda6c327563a734daf0ea246 SHA512: c829e614514a5370c0f7b4deabaf805875eccbd85f456095b287b395c3a0a1c8d16ceca42b829e33381d6f388fb8b0b32da5e104990ae50210320c40dc0d81b1 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9802 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-ros2dds_1.2.1_armhf.deb Size: 2316336 MD5sum: bdbf830439d8c40f7c1e2e2bcd0db70a SHA1: 111e37478539bafa4640fda7d1499a6efeb3911d SHA256: db9d0f2bd57f753e917f9e98d6e410ec57015bd218e3ef3c19d8d04d5cea5b8e SHA512: 3cea530132737a5eae43c3bad0678563f86c409f4ec49e88edbfa422bd94818afa85bd717524eea34e1c9f5a2a70f6983503022865252fda45bd79cc1cb6f67a 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10615 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-storage-manager_1.2.1_amd64.deb Size: 1986416 MD5sum: ad7a045e56a1df48e26ee4c6ab3f17c0 SHA1: 530a0e73cd9ff68a94bc9499f77f52a7a0f16116 SHA256: 981fecd5dc9379ba3bfed806b9a5b4481c35a5b80eddfbc275126deb23bd3358 SHA512: 4796f13cf8a551b446003303b9a46ee2da635064064aaa38cc02ff439d101347f06f52979a4fbbdbb3c4d1648392d7664478123cf5b611a905dedd3830d1d56a 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) Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9580 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-storage-manager_1.2.1_arm64.deb Size: 1815208 MD5sum: 2f2ffb9d74f6bf4a803cf14e731c16af SHA1: 9abf0437f768063d109d3300804d32162e7883d1 SHA256: 17ff413c35f5ff9b8684ddd4f7ec8bc9e4f7d35831ae537ebaa5daa6a84b324f SHA512: 081e651e96000e7f96b056b76a39be7fe99b5b818baff43bfd9f43e5c741ebcd62b47534468831cb76ce544ab90da4a92a295e8295c4139f829c5b7561f39eda 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) Package: zenoh-plugin-storage-manager Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7779 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-storage-manager_1.2.1_armel.deb Size: 1707780 MD5sum: 080f660110564e4ad9a2c0b6c8f4dd12 SHA1: b84205fa7f86cb818c3d34061efed57e8546dbfb SHA256: 82bc17972915673f21b882f2b0856cae6581a2934b2311089111e5e13370bfe3 SHA512: 019cae9e29c01529f0c083e8d4ad58f8a6f0abd9f49195e844ee6f2ffb3b37a58c3919701560161a7723ed3f3ce05eb4a8331507c633a98f8261c40aa159f159 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) Package: zenoh-plugin-storage-manager Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7666 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-storage-manager_1.2.1_armhf.deb Size: 1695028 MD5sum: c9ef3c04ed51eef2e6d3ef4d30259898 SHA1: e59995b780c19031261c4bd93f687fdefa275358 SHA256: a097b5716202a3720d686be877aff151f4e1b9f98010418cb73eeec58c2161ad SHA512: dbbabb3dc3e5230e3796a81a30f69668d1b4ac6d0fd26a2bf693a952e3976f62c64f95add59c128a7be0fd21e42d4362c75bdac21cee190dfffc0c0da3ff44c2 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) Package: zenoh-plugin-webserver Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13313 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-webserver_1.2.1_amd64.deb Size: 2521080 MD5sum: 267920f44c850b4011404975fd2da8a9 SHA1: 74b6bdb36dc053641f3764368140a7c394c2df81 SHA256: aad8a07df3fb1efc33d037db5bf839c5c2c01936e30940acc3fbb22d92d57162 SHA512: d3378e8f8367799d215675be7fdd383ceb9af14bb4e7bc9d5fd5a5e022c627da33e0131651e1ff8bbaf984e4a11737a159dd36f0dd07a13992c0e2d0b15f9470 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12504 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-webserver_1.2.1_arm64.deb Size: 2351276 MD5sum: a9a052ff39f36dca93c979a3b92a5a3c SHA1: 42ec48b48f1f8e60824d4d2786496a871c231145 SHA256: 8ac5fd522722f7cf954aa4de3cff28c6aea840846656f348e18b6af2d002d1b8 SHA512: eaa0f3c07fea9fd4d58fee85fcb9f2ed633c5f902867ae172fc950b89f07cb86426740823a50f0a1d0a5f874a18289d8ee6abb9880b301fca48d25b0c91c7ea9 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10219 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-webserver_1.2.1_armel.deb Size: 2150584 MD5sum: e00677b228ae35e5c70eb6df864cdea5 SHA1: 9ccd64cd87b2e620316277e8de70ef6bc8669ae3 SHA256: 2b77b3e8143457075a0929a84cfd05654d578d11fc032b724a62ad4e49414cf4 SHA512: 3b0d41f3a67c954e299f50ff269c3569cdcac20cc25b1d1390ed82fb7fdc95b77a1ea1831b922119572637015efeac6251047bfcf26e64cca51743e1207596a7 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10089 Depends: zenohd (=1.2.1) Filename: ./1.2.1/zenoh-plugin-webserver_1.2.1_armhf.deb Size: 2137960 MD5sum: 608faa84406ff57b18899a1b93af013c SHA1: 71ea16b55502e245f24836d797c60da65ec5eea8 SHA256: 744b240979f377fc566201619e29671b28e356395ba1d44c586926750f2d8785 SHA512: 39f61a2b45406be7ba02cefee4d9c1a2f64edeb1d7c590dadcb7fb28d2c35d6777d257bc835314fde7c8e6f69d053be67f0f99f7ed468d339a39ded7633fefdb 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.2.1), zenoh-plugin-storage-manager (=1.2.1), zenohd (=1.2.1) Filename: ./1.2.1/zenoh_1.2.1_amd64.deb Size: 17460 MD5sum: cb9b1cb575a966cb4947ea62996a1705 SHA1: 6db8d4e813f34f1a7d622cd6128c87367e2cd6d3 SHA256: 6f2cce8171c936648698c99a181f0a4ef3d3588c443848a716c9a74c8ac3a6e2 SHA512: 01e34cd9e1b8cef337dd8f946c5de217f2e837501158d0739c973e3059c8f157fadca677d40182fa4eed4fe1a3ebe5e53a1fd216d61628de5dd2443d372702a6 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.2.1), zenoh-plugin-storage-manager (=1.2.1), zenohd (=1.2.1) Filename: ./1.2.1/zenoh_1.2.1_arm64.deb Size: 17460 MD5sum: c5f985f72a9800183263059e0e88f5ff SHA1: 9e2ed5b488060f96ce70c96182da9c7968a65407 SHA256: e84500532c6de2955ff155915fd060f148986cee748bc3fb5e83b65eb8c2c528 SHA512: e8be2e9695970fbd21a1dae8e599d70ca183e62f056689dc7a53854ffbff91128c62d3f5282de6b86c60d7e5768d77ef445cdb2b52bff3044a48c6b690848650 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.2.1), zenoh-plugin-storage-manager (=1.2.1), zenohd (=1.2.1) Filename: ./1.2.1/zenoh_1.2.1_armel.deb Size: 17460 MD5sum: b4c49cf6e066cf25680253963a82190e SHA1: bad9d82dd081e36b4be84220f3b2423437c814b9 SHA256: eb1c7cc8e0be6cb452b4a19fc1d73d0d527cba2427427863982c411043cef5e7 SHA512: cd0fc05a1c9af35ee0d1b79eb36672491696ba578cc4a6fde763e3ec0657c74a455f0455134ccc23b396d004d6161d3fdad1bdbd300c9e14091dd2a2438f71a8 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.2.1), zenoh-plugin-storage-manager (=1.2.1), zenohd (=1.2.1) Filename: ./1.2.1/zenoh_1.2.1_armhf.deb Size: 17460 MD5sum: 06f119582d6ef6f58f67f8eeea01cb7b SHA1: 9c54983c578d15cd13324091029666daa8d1ef95 SHA256: 071782a27f75863dcb89506d96050e2b62e37be10320399f53c3053db1714919 SHA512: 1b64ff01c4129c6af33721fbe57ebfd515c6c4e86d6b8ad618722f6ec93749c579fcbabf3008d651c38e499f2c4e6bc272b9cadb5fd71e104931d44768a7511b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: amd64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18505 Depends: libc6 (>= 2.29) Filename: ./1.2.1/zenohd_1.2.1_amd64.deb Size: 4513756 MD5sum: 6c6c464d526fa60a59028ec1382981dd SHA1: 87cd56279f74bad4d46545e1c990e264276db815 SHA256: 09afc38ce5868f98ba03b9d00be010a9ed0d399bcde7ad22468ebf5446d29911 SHA512: 3dec7a1aac11122917f117cdc2998b6b1c1ce0532f94f66b2cccab18e54942f1e90ca5c105c9024f17b6800496651e313e3fbf1988355599454c96b3c8d8b8cb Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: arm64 Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16604 Depends: Filename: ./1.2.1/zenohd_1.2.1_arm64.deb Size: 4051664 MD5sum: 2bcf8d6d349fd7350262b8d82a9f2d96 SHA1: 1ae1daf1a5338fbf12c5b65e2b3c7212b4417ffb SHA256: 9d0e00fb65268d0be65ddfa7ccd72a7cf362698d2fae5ebbe668271085314a50 SHA512: 4292e4b036772e921155516b9903ec4e0e241493ac366d2658777ac0f784c337671944d430128fb4c7b7ea993bbe2ba0172fa468c82165f6228b1eafdb710d5b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armel Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18062 Depends: Filename: ./1.2.1/zenohd_1.2.1_armel.deb Size: 4432792 MD5sum: 555ef81419a12a5cc73e089be908a357 SHA1: 6412ab4d6460e56e67972f8bbd3ba8fa8a471489 SHA256: 8ec4bfa30efc8f2eef124146e48bdac754764ff21e2ad016783950dca7df79ce SHA512: d22d0bc0933375f309d7da12edc7b948143572de66ee8e64f6c56a563b9ac98c8002de1ab8ec5942bb25737334623639c3bdd0699abd77b6690fb5bacff1f80f Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armhf Version: 1.2.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17831 Depends: Filename: ./1.2.1/zenohd_1.2.1_armhf.deb Size: 4484964 MD5sum: bb83b75382451a75f53b437fab0ec04a SHA1: 104e91e7872553d12b6563dd1d5786d8eadcc0a8 SHA256: 99c6ca750218a3967def5906f683ad4ce57e8c7c37092ff69bd2afd0acc4cef2 SHA512: 3a70f7cd3f781a9fa3a0f051fdac3602251e17d68cefbccb7909fc7f1268a687c8ac37c24e3e2748b2a8a5de892a6aa4dde1e6bc423ea9055d554dceb471ac17 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: libzenohpico-armv6-dev Architecture: arm Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1231 Depends: libzenohpico-armv6 (=1.2.2) Filename: ./1.2.2/libzenohpico-armv6-dev_1.2.2_arm.deb Size: 246164 MD5sum: 192173970f9970700b8149c892575953 SHA1: 2d9b3ca9eba3a19c9a4e603460a4a00f9b9a4ddf SHA256: 356cfd54e0ff92195c52914709f136b2219e08355e1213899071628a8d9e9675 SHA512: a676967aa24a5e0da69bb1e35e5b043627fe69a656772f66756f283bc62017dc437eac44a29d097bf77fbb9bf1233987d4c883eec22c6aaf7fc4be6c93e07457 Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 354 Depends: libc6 (>=2.12) Filename: ./1.2.2/libzenohpico-armv6_1.2.2_arm.deb Size: 145282 MD5sum: 4f46391d80227639dec91b00b890187e SHA1: a620b23ec0d8a67c1729672a0ff481c846287c6b SHA256: 070a98ecd7c61b734bd8769e7d6d256c50a28ff27be7ce43c072ff18a5510176 SHA512: e43117e628edbbd2dc61213423a18bd425ca49c1cdced286faa2fd1d5f9e7f95b68099308b7b7f46ddf3c87e9ec62f4218089b04497cd25c86eb7f8f5ce07afe Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1223 Depends: libzenohpico-armv7a (=1.2.2) Filename: ./1.2.2/libzenohpico-armv7a-dev_1.2.2_armhf.deb Size: 244392 MD5sum: 9c438be2d82fbe31c04f1f0ef8964911 SHA1: 41c854e02d579943967f3adc5ad55815b8e49c70 SHA256: 47827d00a22d5e5cd23e2dfdeca1b8ee357e45a4d0501ce9d7fe9e16d3e459e8 SHA512: 588ac07b2126c81a2bc1e26ad5c31268801b38edc22e9fab92d88fca7bf14b0d23cc8d3782e891b8f778549732748a4177ab4da44792aa9222eaf4656dd5efc2 Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 350 Depends: libc6 (>=2.12) Filename: ./1.2.2/libzenohpico-armv7a_1.2.2_armhf.deb Size: 144604 MD5sum: b54359c43ab3b8ee9ea5765981d9225b SHA1: ec907a89904f2a7c7a71de865f35b5d3fad89aae SHA256: e32da4f3b4cbd4251e5731890c1c4c1137632077056067a81bf82ca536c0f258 SHA512: 5a1c85cf13b46354fffe091967c550e2004413947d91f1d08fb3940745ac1253ed212512a3c21c4da778114cad14f48879206759471e418c7ed0a4111ad983b4 Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1477 Depends: libzenohpico (=1.2.2) Filename: ./1.2.2/libzenohpico-dev_1.2.2_amd64.deb Size: 292592 MD5sum: e9f44d55d6932739933f00babc5d768b SHA1: 7c8663fe17ea963cafb531209b661ca915008acb SHA256: 1a3d0251f29e5c327a592ca399c1312c72b1470b6cdb003e64441b3c452d014d SHA512: 82850c5b3986fb3aee189327a6a72e47c184b4709258efa637487848837f8d6762338c8762561f335ae29c271bf8f3f90c0fd28b4a469deb8ea27fde885fe2c5 Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1230 Depends: libzenohpico (=1.2.2) Filename: ./1.2.2/libzenohpico-dev_1.2.2_arm.deb Size: 245718 MD5sum: fd997b78c14428e2bb5125d2106d91e4 SHA1: 5784d5aefd9bf18e3445204f040b56f2daddfade SHA256: 8c176e25e3afbda5801b02014027948207f341c20093ff42e377a92e6f4f0c87 SHA512: 96434a2cd926729e2d9ab117905498ab3af8dfccaddd3b8ef41e1710ec55e06b737babc3c9d6d2e1e3322078ffcf1a22dfcb80f093d67b77ad1e09f5e44dac76 Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1487 Depends: libzenohpico (=1.2.2) Filename: ./1.2.2/libzenohpico-dev_1.2.2_arm64.deb Size: 288516 MD5sum: ebba9e415d9a0bdf7717207ec9bea3e8 SHA1: 97913b5b85b96797fd8ddbacd39b6cfa6ae2eaaa SHA256: 9ba7722fa2e3e7ac6964d6c9bbfcae4fba54ac66ffa80c1f32ae108f393b9f20 SHA512: a9ebf210d2972b92d73c904c8f156261c71affd5be3419316039aee2723ec351576c089fd3c1aea58edc51eb33dc4a8781661563e7853536d02013f2d9016831 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1224 Depends: libzenohpico (=1.2.2) Filename: ./1.2.2/libzenohpico-dev_1.2.2_armhf.deb Size: 244182 MD5sum: 43a0ba9d553dc072ce2fccb9d13b4faa SHA1: 595c855f8e0ba264497fa3538977a180da8a4cab SHA256: be6117c9ba46558a61a60d68612420852d69a1709b14f40bb7abd126dcec768e SHA512: dde7ac5a48a6ce1db371eb875272fca8d091383e89a2edab71830bb2716c9433c1d9d9b7ccd90267086f9e2a437d3f0cc5160dcdf637c52f9cd451e91e46bf8c Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1449 Depends: libzenohpico (=1.2.2) Filename: ./1.2.2/libzenohpico-dev_1.2.2_i386.deb Size: 318304 MD5sum: 85b4d81327747882aa599af66138be58 SHA1: 218d0bab282f3b1c89bc460acb362b8efb6f29ef SHA256: a6e66a70ece3a76af6b6728e4e4fd92cbbf223620588d6a68e755d07e671e0af SHA512: cef6f3a795f269ba1d544c326ab35c2b6fc88c9f49388161253a09cd17440a9b2c07975587e42db4fdd11e5b55b54495c9af93cfbfe472d444d3b1b7c622935b Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1375 Depends: libzenohpico (=1.2.2) Filename: ./1.2.2/libzenohpico-dev_1.2.2_mips.deb Size: 276920 MD5sum: a59ebadc224aa0f4d0f541352d6cf4e7 SHA1: 5b60f0701a4f5c95a96c232aa3531065b374fb58 SHA256: 6ea9c3005af92fb5a0d1929fd8e19b37ccb7df71046302516c352a2c063168db SHA512: eb6465c5ff26755c28ce72fd9272f35f45794c0410dd038cc66e8fa93ff8e3a85f6f26e2488dfeba97950c565c64ae8aa82524d720cb8ac773fef9318139aaeb Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 482 Depends: libc6 (>=2.12) Filename: ./1.2.2/libzenohpico_1.2.2_amd64.deb Size: 176678 MD5sum: c1cc8ad00064be1806a1809b7308a561 SHA1: 2574d9533b73a9dac68de5f73a43bdb93fdc370c SHA256: 95377d577983dfb075df78bd4cf6609733f820b7d963b3bf2c5ddd5552cf7228 SHA512: 2d42ea7a0d92ecbc89bfde7bc64ee86ad16b4fbfa6e72496b229a3e9c72f7dd46166a375fc39ae26bb6364e9edb7a751ea18397eb9d22ff28950e6e581130bd2 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 381 Depends: libc6 (>=2.12) Filename: ./1.2.2/libzenohpico_1.2.2_arm.deb Size: 153298 MD5sum: 0ea47368202d6fb15e1f245831a2c569 SHA1: 80ade09cd7106e75de705250a1dabfea5fa4da2b SHA256: 0578028b9a72751ec06e7a81799f0356259a4b2fe4f03b6d9ccc140534ddbbe0 SHA512: f8f5127908f10a0e97cd694ed7a0719c520c39afd2bee2f8ee01f897f73fa29876507a44549ac36e348616035c2ec7b6dcae371b725f130102f8e2c5f44b37b8 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 492 Depends: libc6 (>=2.12) Filename: ./1.2.2/libzenohpico_1.2.2_arm64.deb Size: 174640 MD5sum: bc6d76ae460f5373d9a347c5cd2122d4 SHA1: 291d0542b578a0e812b1aad94771819ca0a22c34 SHA256: bda9fcc6dc0c9b7368585eb3d5523ab0d5a0fe8f9a7f33c9f026ce81be1af4d4 SHA512: 53b20b7fdce2bb1e17602d3b0d6b519df850a277f0ad4cd3a050a56f9cce7cf7a81f1f2261b6358a89fd4fe02ca14195d47120ec2759281b3cee134d33ac7823 Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 352 Depends: libc6 (>=2.12) Filename: ./1.2.2/libzenohpico_1.2.2_armhf.deb Size: 145738 MD5sum: 824e9da04a79ad965b4c485043c4df41 SHA1: d9f9259dd246753caef5e13d62dc76d16ec33d45 SHA256: 09797a9ff0879127f776eb99e4f796852e20eabc8326cb0ee6fbe84e59afdf91 SHA512: 2b876fd8d172123c2acb1a7b4fa0133d942c50f70ea14d3208962322b584e9ea3c7b00c6526d2aae432094d87e483149b3fe03fcae4eeddd6889d47d238b74ec Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 508 Depends: libc6 (>=2.12) Filename: ./1.2.2/libzenohpico_1.2.2_i386.deb Size: 201808 MD5sum: 3b4b82e070b121e564e48eb03b4c1abb SHA1: 1e9b435dd37694b0db868abba56d214051e3a810 SHA256: e982c76f276a1b4c8048e7cdd0849a5d225922ecd2e5033bf81200873a15d237 SHA512: de49dd3df563c43e185970d4692b80d0a987d845acbf3c6ae08d56a60e99b1399d7207524b9ee901ffb7227e6d9818f27355790a43723a88a52ee89c75db00f8 Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.2.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 461 Depends: libc6 (>=2.12) Filename: ./1.2.2/libzenohpico_1.2.2_mips.deb Size: 158884 MD5sum: f7154aab1891ff8eda961b24669989fd SHA1: eeca06d158f431b0e1b492bab263889d496fb549 SHA256: faf4b6b0788ba54b0c7227458ceee6d6ef9c354cc26ea2b7488220d9e32e2fe6 SHA512: cded45a4140d455bd1ea362772917160b82f5fffa4504c349aa31946de094c1653ded14916a38dacb4c3956c4324360da424af9fef6244c3430d655d23a8705e Description: zenohpico built using CMake Package: zenoh-plugin-rest Architecture: amd64 Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10808 Depends: zenohd (=1.2.2) Filename: ./1.2.2/zenoh-plugin-rest_1.2.2_amd64.deb Size: 2091532 MD5sum: 632cd77a5fd8d5b66b443aae379bb1fb SHA1: ca6c963246c99b617c616dbae028a2c7c0f38782 SHA256: 8ec2bd5f96720138078c3315bd433da337e2d03257ca56e1628e973fcad00ed1 SHA512: 69df09069408cde7d06d27ad8f4deb26c6cb34b053c2d86c27472e36e555d6314adfbc0900976019cee6b2331560f3a4c4935357d53de38470559c15f181bc0e 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) Package: zenoh-plugin-rest Architecture: arm64 Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10246 Depends: zenohd (=1.2.2) Filename: ./1.2.2/zenoh-plugin-rest_1.2.2_arm64.deb Size: 1962244 MD5sum: 15a615f64654cf6c0930b97a37613021 SHA1: 5f11282baa05b430d869b1494a347c65a909fdf5 SHA256: 4abf81fc1246c9aa862a027e1df71937efdd3f381a57168e81a593071ed93e2a SHA512: 6d0e89caa103e62f78cff71d0e0385daed763e6ef7c76312bd55425a4f62cc9a63797fb69ba49265a044af1144836156ade917e0f6da2344074ba1e4916578d7 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) Package: zenoh-plugin-rest Architecture: armel Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8059 Depends: zenohd (=1.2.2) Filename: ./1.2.2/zenoh-plugin-rest_1.2.2_armel.deb Size: 1806184 MD5sum: e26ca6187b97f9bd80f0d7d75bcb5a27 SHA1: 5c076300b7a663e1ecbe639b25d5768acf68098c SHA256: d5f78ac0ba8cefe443e6d60e294b65aa2a00d3ae3348738407ca3b8ecb5ffff1 SHA512: 743edc647677b6650219f3d318f59afc2ebc4945c55653dedf268abcf485af8f6fd89211833151f2d46db0b51deaf56d99fa2fbd36364b122523177604a98262 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) Package: zenoh-plugin-rest Architecture: armhf Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7961 Depends: zenohd (=1.2.2) Filename: ./1.2.2/zenoh-plugin-rest_1.2.2_armhf.deb Size: 1793284 MD5sum: 7b4e0a954c4d9277a5f95dfa4152559d SHA1: bb69645777930d9462c0b9523cd28d4aea55d18f SHA256: cd2c40a572888ee0a4d25d73326cfa44dcfbc273e6399aded18555db37ec9acd SHA512: 6bc396af95dd0a0c249091614ed3b69fb050a3b0e1c87bacf1713847dfa9fda6ab9e8b1f1d3ce7f99e2b5f7b66f8f0f1938dfd9484852a3b2ec48524d5b0faad 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) Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10540 Depends: zenohd (=1.2.2) Filename: ./1.2.2/zenoh-plugin-storage-manager_1.2.2_amd64.deb Size: 1981148 MD5sum: 266da1388b7e662e5d7a34d274a0b764 SHA1: 15b038536b3c86a5afd575fe84baceba9473745d SHA256: b6a564ba5349bf20923f1a1a4ff858306831cee95e3e83fe5e95905ed009045d SHA512: 181200dcc6ace18d1ce1db357546d5293e5792bf2b3f17fc26ef36d13d013d9e7e16a9fc1a4dd3fa8747b642c0d6af7a5f21bb056a1e7d68b4d76d2bc5ff4234 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) Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9957 Depends: zenohd (=1.2.2) Filename: ./1.2.2/zenoh-plugin-storage-manager_1.2.2_arm64.deb Size: 1854952 MD5sum: 41ad390e96de1adc901ba64619a650a7 SHA1: 2425aa5ddbc9427cc14ac25b593bc0ea4c26915d SHA256: 8fe8bce4382acc0383dcd74709fab63caab5413c72e3d80fef22bc1e37f0365b SHA512: 040a7a5fbb7bb15a52b5757edfe42bc2c7d7192476c528cab1e242eb576b09317bdf85690128cb7be77aa8f8213d9385a40858b50fd50ba91693806f2b058dcd 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) Package: zenoh-plugin-storage-manager Architecture: armel Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7817 Depends: zenohd (=1.2.2) Filename: ./1.2.2/zenoh-plugin-storage-manager_1.2.2_armel.deb Size: 1719352 MD5sum: 5dc0061f0a83f204c92b1261b674163c SHA1: 40c929d3e5e730b6c15b2d3eb316b56f37286fb0 SHA256: 8911f3c9a39d26863151dbb83ac632950381c7afb8a0b6d7be65c69fab787ea9 SHA512: bdccd1b68f286b0526b5b5239c3f89b301df779552d1585f8bcbc0fb428328d62789f4359937a6a53130773d385a0876fe508bb32600a4ec77b5fb4d5dd63583 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) Package: zenoh-plugin-storage-manager Architecture: armhf Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7702 Depends: zenohd (=1.2.2) Filename: ./1.2.2/zenoh-plugin-storage-manager_1.2.2_armhf.deb Size: 1707432 MD5sum: 43a7a41c035fc262dcd35d56351aeeb4 SHA1: 0c5d189f8669fc79b4ecc655de2dc4ab2e584a75 SHA256: 332d61ea0ee5c60769e3a514a50a4233bb149da0e2f23ae5492a9987b2075b40 SHA512: e3aa29d479c7cbc8f7fb587fdc88a0efe7bd3fef1a273c8c93c9be954a0daece6f69f5af0ffd260cdb34b0bf113ed0f320ef28f10f0e7bac1a287d64fc65efbc 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) Package: zenoh Architecture: amd64 Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.2.2), zenoh-plugin-storage-manager (=1.2.2), zenohd (=1.2.2) Filename: ./1.2.2/zenoh_1.2.2_amd64.deb Size: 17560 MD5sum: 0bae52ad4cd6bb5a2a55be1a6b9cd61a SHA1: 263ec12dfad109338bb0e94cb5b55045ebcd3cff SHA256: d8eccf0d1d0c8c1bf5cf1af2cb6516e9762980a8f057f92878bbfdffc252606b SHA512: 70145a58697bef8d2ed9b9dd5637a81e8c27329ed0a3e87d801816e9221854e44fdba2946996f698dd854cbaf9f419b9c3d37d03965e4a60d834a34494b09ee6 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: arm64 Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.2.2), zenoh-plugin-storage-manager (=1.2.2), zenohd (=1.2.2) Filename: ./1.2.2/zenoh_1.2.2_arm64.deb Size: 17560 MD5sum: 4b11ab86cdf5e94532b36d0b9d6b6a79 SHA1: ac72268b7fcacf97d35d18e17861af8125ada200 SHA256: b07fa57a7f33ead34ae5d1997302dc9bdfde9f584139b6f140a686ef71e8f93e SHA512: 8bd5805006bdb686b4daa75ba34366d4b5a1a0c866bc70089c32c22fce1d5ee048cd30fa98dc0e1a41229136d7e551f0e856d22ceeef9e5949da02f45df46d47 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armel Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.2.2), zenoh-plugin-storage-manager (=1.2.2), zenohd (=1.2.2) Filename: ./1.2.2/zenoh_1.2.2_armel.deb Size: 17560 MD5sum: 93f5ee054fd1872876bcf37e96df112d SHA1: 23358de20fdf73ef120fb45bfd728b09ee507d51 SHA256: 2ad99b975bf046615d037294c31fdeef054586dd96a3aed1e6794409e79869e9 SHA512: ed0411e7e9c4751bd2d3dc88d3ea2e887fe3590a5df2fe4f1c17ba1f977cc261370605846799604fa52ad76353351581b4a489f835dd5357eeee597786c27efa Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armhf Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.2.2), zenoh-plugin-storage-manager (=1.2.2), zenohd (=1.2.2) Filename: ./1.2.2/zenoh_1.2.2_armhf.deb Size: 17560 MD5sum: 89a1e583d2ebb0fef356485dc6bbc312 SHA1: 52ec67eedef4f695611d097da6dd35b03a65505c SHA256: 11a2b749e37cf9ccc527d968a634d3251f5a4354dac676d4df0f52649fa49bc2 SHA512: a9a632440ccd917697ac996dc680256c70e274c3f6e3f290c918ce4fb8f89bc40e8b8c50d81eddf87ee160584a2037c6a1244ac390aa686636cbc480dd9c792a Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: amd64 Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18522 Depends: libc6 (>= 2.29) Filename: ./1.2.2/zenohd_1.2.2_amd64.deb Size: 4534772 MD5sum: f9f77326fb4df0616e0d7688f459f629 SHA1: cdcb6b4f6f8078079dd76172c03e508e26a0875c SHA256: edf805283c6a3cff0590d9d84d4f4af05119b3fc9b5f748bbb62b4f4703f4f71 SHA512: 92866eca112599721b68de3b07562e6362c3b08808c62d2c8fe1d0de564b1202db4e61848115ec6c82002642b4762e61f813b8e3ddd77ff283d452ac33a2483d Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: arm64 Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17055 Depends: Filename: ./1.2.2/zenohd_1.2.2_arm64.deb Size: 4138140 MD5sum: 34c400231c521ba707df5898d0e16635 SHA1: 3bbc816933f6f8659ea2c64bf9b7d25439241758 SHA256: efe721f7666e1f90cb6f5072ed2f96cd081b90cbf6e3209d151a0bd24369d31d SHA512: aa06571b628150b4b0198ec7212f37f23013df5012f8be1893a6d4e2bf23c2ebddeffc08f9d77c85cd806f5581ab5cdd9959ecf7995327bf38f78f30d0a76023 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armel Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18175 Depends: Filename: ./1.2.2/zenohd_1.2.2_armel.deb Size: 4474932 MD5sum: 07871ec680f4b2c6295ce314d63968f3 SHA1: 2536bc7e19d1dd7ac186f76d57a641768f6aaa82 SHA256: 92bfc8dee31868240ff55f81c7fa61ecfed95c5223bd862ac6b5bf4d622a68c4 SHA512: bb0f25ebbc9680b72e2e383b422b691500c24b268f245565cd8c42860edd5a7d8892f22430e8d4cb3b79909c228aa6ff1b8d927149c1dbdbc66f8c68e30aafac Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armhf Version: 1.2.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 17931 Depends: Filename: ./1.2.2/zenohd_1.2.2_armhf.deb Size: 4528052 MD5sum: 0d2c834b086a5d1aa5e7257d4280cee2 SHA1: a87a3c4143b3a28ac096504f25e4b5eff15042bb SHA256: 0511b21460837c3c908932b627b283ee79c5ae5a8a71583abb0b3ac3056b8b22 SHA512: 2543eb7d4dbb1535f8b8c9896995dec868e3d807aeeb460a5fd6e2f4cee830b0b1ee186550d29861a6e9977887d6ccd8be91b5d25def99b14b5d8a4937dd2864 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: libzenohc-armv7-dev Architecture: armhf Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30142 Depends: libzenohc-armv7 (=1.3.0) Filename: ./1.3.0/libzenohc-armv7-dev_1.3.0_armhf.deb Size: 9370134 MD5sum: 7347d185156c3467e01ef492c1981d31 SHA1: 4294d376d76c95383ef8d1e77d39cf81dab3493d SHA256: 1798b7739a4ea883c8d97b12225f5abe2bceca30d91746146fe66d8f4306f9c1 SHA512: 7f7a4fbce9c0636add1464e39169441c759d4d982ce1d0c97013d1e627418d899003feae063a3c1e045878688feec2dfc5c1420c9cdc60d5a00ad8f1ed1a66c6 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13095 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohc-armv7_1.3.0_armhf.deb Size: 5537580 MD5sum: 021a9d8079e9114913271aada438d3fc SHA1: 3550a1cb8f6fb05244c37da866d3549436e68342 SHA256: 040b1af408d0fa6607cf36bb0c35a05f986eee59ae7f479f03ae969a24dbbe55 SHA512: e5f8afe7fe322c6c749e861edcfa3aad39fede2a2c218610a7c967d1cd0131530584d0650a480a11f8c80fd427bf750d175db72a29b7ff615d7185783e3267dd Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 38312 Depends: libzenohc (=1.3.0) Filename: ./1.3.0/libzenohc-dev_1.3.0_amd64.deb Size: 9081382 MD5sum: 1c6cb684f662511fad907f7786ad746b SHA1: 17c323b60ecca67110e3995ee364c299f80db5e9 SHA256: f436dd21871bb5013f3dc1b250466744db9f91e0fd5d6a5cde8d2e4cc98b756a SHA512: e6cd804f2f3fac80bb2cd69e24ddcca30533aa1ebcc7c370012aef7f585ad403fe33ebee7e525023d52b0b296ace0c9c23d6d961b6f78fd0d557feea95280231 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37241 Depends: libzenohc (=1.3.0) Filename: ./1.3.0/libzenohc-dev_1.3.0_arm64.deb Size: 8766876 MD5sum: 77ad5c47ca29cb01f714041ff3eb49b2 SHA1: 226b79f324468f9b3c25a9068743d58471d7e05f SHA256: 2836a4f39ff2e55b0167992a93fc7f3b8d1133fc2264506febdcc7a47b58b128 SHA512: 70ae91f2049b94817f13ea1a0536787951212560323d460fda77f98506ed455f22f760b4d200306d0c5d3594c10c9608a015430c07b285ec1e3d51bfabae03b8 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31016 Depends: libzenohc (=1.3.0) Filename: ./1.3.0/libzenohc-dev_1.3.0_armel.deb Size: 9555370 MD5sum: f4ecff5638ca4ad6110119f4a3c6f39f SHA1: 5dadaec363b9cd2d71d1c974bc881acddc010f98 SHA256: 0872ca4a357e9ea0abc15e550d2ac3d57d5b90b03b21fdedc88032ca47bd71ce SHA512: 06fad29cc593780b703f7e477c0ef9b1b3ed6dd219e80c50927c6da3e21628b0402b888592e3678d46564e5fb6f6ac6e262dd2123ac7139f7490ebffd20ba8ab Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31161 Depends: libzenohc (=1.3.0) Filename: ./1.3.0/libzenohc-dev_1.3.0_armhf.deb Size: 9680202 MD5sum: 5b97c03c0311963e6dead34872d46b76 SHA1: 42ed1d0764c9037e8a51f3eee39c25de9168fa52 SHA256: ae329acaf33fc8a5736ff93fc6345bcd881639f5a1875ab32ae20782ebe7d30e SHA512: 31dbc7e3487dec77017864351aa07b5cf3b8c7e3a97361e68c36bc5dcf76e4846f0727ab0212e962cc9da5ff4f03002b00c4a1f65d5262ae07630b382d5d730d Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 34315 Depends: libzenohc-musl (=1.3.0) Filename: ./1.3.0/libzenohc-musl-dev_1.3.0_amd64.deb Size: 8853036 MD5sum: d7495156e120ae01c1219235e5cd3a0a SHA1: e507d40262be6d123b85d0633a06a422261636c0 SHA256: 6d3d0656c8184dc7065b6bc86ab2762ca4c59e5a4c7dab29914a3a41fd1a5373 SHA512: f33446b82a41affe6e8f1352609c9e5fd631a2bfbe2390148d97e05938f00a52b3bfaa4cc81c13a26b32f7c27f9f0f192b33ecb1e83b5d6fcd0228794080a08c Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 35231 Depends: libzenohc-musl (=1.3.0) Filename: ./1.3.0/libzenohc-musl-dev_1.3.0_arm64.deb Size: 8536058 MD5sum: 08c8a4cbed2ca452914f6236f5b5b082 SHA1: 799724b5b8c9f85763df3aa815b7223c3fc33dd4 SHA256: 8a9ac6c1eb0c97c80081b222b7b37caa64006c312e3f15dd46b84afadcd5eda1 SHA512: f933c4da8ff641efdddb75f25e46ef1184b01c91129a9bca118bb042c05a3801b68cc69f153990c3987998e8cf02161a46d74cc1edbfa0716ad7932eeafa415e Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13916 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohc-musl_1.3.0_amd64.deb Size: 5554048 MD5sum: d4459620273281bc1539c8a8503ce31a SHA1: ef85731f8ee14bba62e202eb12836c5d440790ea SHA256: d266aa30c8bc14bec29bf219571fa548d3930e2194c7aaba677330317175f0a5 SHA512: c6f7b3c203d96d24585a06e5e6f0c9f526556dcb8eb0b1bbeccaa41664087a8978851cf660a626a9f722fc30ff3e120c454463aae7647b2c2b28950edd59f117 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 12989 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohc-musl_1.3.0_arm64.deb Size: 5292780 MD5sum: 8cffab08af7fc939e40233e82e868a2d SHA1: ff1243ae09198ff9dac3a85921f7bb9f3ec25184 SHA256: 58d0e9136336f03987e0f398b7c2621b0133982e3dbab8d69ff439f24b2649d1 SHA512: 214cf3b03c87789a642f15f5f5d83c31c8630dd60d5ed4e17baf0b3fc2d9864178acc492ce5fd6d0dcc84afe8315e09a7aa84bbbd903a3cbf48f7dc7856a4907 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13923 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohc_1.3.0_amd64.deb Size: 5560644 MD5sum: e1c19822645aa4589a2f6944f5efe051 SHA1: 394ffa4a052486c845227c968eb76411c78b2fdd SHA256: ba50457cd562506ab673e168f4c42fc796b8393ecac2af65ec4a18d0e68a40e0 SHA512: 7d6ba239f051442f2716c27dcba91fc7ce702435cccec47ae1d4204224bd9df5e0e6323d0453e46100eaa3595463034dfaf2bf3554094342d94da3c2adf2d0d7 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 12968 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohc_1.3.0_arm64.deb Size: 5319892 MD5sum: 12c5945159e08f532d803407a58e33e6 SHA1: 3845cee2c0d4395093054c051840c097e8cecaea SHA256: a22447e7dd8087c0558e4846f1a24f7c29527559b1272464e19043ea50a174eb SHA512: f1374910d52e7aa17a4123d84359660a99c9d829dcbbf0dfb76ea37e8238e2d90cd34c552e95318b1e16eac82809d943b4babc67b443e15baba091c028a4b348 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13378 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohc_1.3.0_armel.deb Size: 5628200 MD5sum: 14e0a49b732bfa9b9630e7d80d1ee6b5 SHA1: 747e25573a1e9025f0aaba71a4974c1b1a9c2025 SHA256: c705f42c7d6bb011b999e83a34d601bb8d6e75cce9d5e23364e85270a5f6bf90 SHA512: bb2832e04b11a03576f41465a22b577967c59d352178ae569db68cd0f0169d3821bdd79b7a8c210d9f82d434cd65799d9f4349da3502dae00602b1034d2bb118 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13386 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohc_1.3.0_armhf.deb Size: 5703692 MD5sum: 03d0a7ff0df0008fecb46b3474bdf186 SHA1: f3060e187e6f5601cc9acfceeef59e4eaca608c4 SHA256: 908d3c4ecd19163f7d75ed6cc3ce095661f8255a94beae2d1ea9a928d6615751 SHA512: b02d0fd1be6619557912c9362ada21daa60b47dd86cf6efe7e6b9c25fbe45f29d169c26fef8e1a7eb9febdcfbdf84ea8cd2660f3e036cdce4535041c24d48904 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 445 Filename: ./1.3.0/libzenohcpp-dev_1.3.0_all.deb Size: 57002 MD5sum: b4b8b2b7fc878ce8fde2303dc3f66e56 SHA1: ce8d077e3201bfd20e0180949b0b8119f55dc921 SHA256: a294c55c68a2705f16140263d8fb3d4311c9197e58f50ba8e734a9c65442c7fd SHA512: 42e3bde478b640161b104b445e03647c220708bdb6d6fbaad139454064bed95cab5663839644af754158550d958f82c816aca29429e7e416c72649a4a6a22fe2 Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1231 Depends: libzenohpico-armv6 (=1.3.0) Filename: ./1.3.0/libzenohpico-armv6-dev_1.3.0_arm.deb Size: 246160 MD5sum: 1283afd5ad25317623c2207092a7c820 SHA1: e3e9f879885db78c732eaf89ba1d05d6cbcbaca8 SHA256: d8688d80c9f19f7133656d3e8c0f3c39f678287c7821b454044f405ac5cc7527 SHA512: 91bfc85b095b75b334aee6f2af732467de2303a9740830e9e79f7cab332dd51be767b207cbb3a74f8e4c35bbac25458f621c565f180802a525750c13464d0980 Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 354 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohpico-armv6_1.3.0_arm.deb Size: 145280 MD5sum: 877c2a997ce1c275d5d374a76401a381 SHA1: a69f2ef5aaf320c7e28fb68d4ec9110353946f7a SHA256: 552b3c142a31d07f8b31cf1b21b67dd513ad23f8dc17bc99d3b8884799c4d253 SHA512: 1dfad30d00387c2bf7687cd0c4f877901259a12db740ec568e239482ebd1fef310a3f36f02387fd7628f56865c58ce99a9684e672431932fe2a73ddf8731dd4e Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1223 Depends: libzenohpico-armv7a (=1.3.0) Filename: ./1.3.0/libzenohpico-armv7a-dev_1.3.0_armhf.deb Size: 244394 MD5sum: 70988ca6c04d8a66147056d9954c3104 SHA1: 0a99fd99d3e6202d13067b9c39334d8a92a4356f SHA256: d00a066e7662ac9bb18ff2e1ea996bc12ee6c9cf775d2dad4bd682cc00bdd138 SHA512: d8a157f7b493966f598f826917f5f311d4a70e88a7713965d3cc3e1c69cafa06e2f56d8893a18531603b82d7bb84eda9f728c04c8be0e6413d5a93bc85540bd2 Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 350 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohpico-armv7a_1.3.0_armhf.deb Size: 144602 MD5sum: 95f0a238545d74cd90148d48a0506fe0 SHA1: e1b5e2f3c0498a6dfde2d6a6703faab7dc015cd6 SHA256: 9bc4514469e91f4fb28f574604e522f8de1636052fcefe33d4da039e673cef3e SHA512: 6d25b258fb88ca6fd5ed12d71d329a967df4f30f04c9c6b6d58b9f97dc81a2d72c3d61017fe1aa5a84e0e5b9dece1308af2fd61462da392ac642399781794f62 Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1477 Depends: libzenohpico (=1.3.0) Filename: ./1.3.0/libzenohpico-dev_1.3.0_amd64.deb Size: 292596 MD5sum: b567f6f32d9d5ddde6794dd6a9aac75f SHA1: d8235f29c06b5589ba4e128a40c3f6a181071039 SHA256: 69837734c725c373a50c96bad50ba48a9e70281a2bdec8d9c83971700d1d3be6 SHA512: 401b82bec2193f0bc6aa636b6dfb388752b0efc01e4282f2154f0875f392e0ccb0c8527dad330c5111281e7b5822d28842006b38b2e0656ac98fa2a319cc7b6f Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1230 Depends: libzenohpico (=1.3.0) Filename: ./1.3.0/libzenohpico-dev_1.3.0_arm.deb Size: 245716 MD5sum: bddb0afb2439c9add888605c2c99fbf8 SHA1: 301b8ae28c8e908263b6b3d02662f2c34ed0fb8f SHA256: c1f34ac882f3a8fe734128307028829d8e5d1275401eb9279429c3f0e185c08e SHA512: c4ac2cd9a12b816cc31c018c32b64576d797e716dfaf2a07badde089732f596e3c125a312478969cccdcfb2441b261fe101aa703acba7bb9b7a7b00b38ac8247 Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1487 Depends: libzenohpico (=1.3.0) Filename: ./1.3.0/libzenohpico-dev_1.3.0_arm64.deb Size: 288502 MD5sum: 82ce468dd6677c27a280dc73719d5a6b SHA1: 17f3c45a1f504e6f48ca1d90a65bfe6d811518e6 SHA256: 5d13608d1b5e4add1113f4c7a510db198d84dca4f5c5a07f286bb6f9fe45a9f3 SHA512: b28d21b5444646e409688ef4e3b55858de0da40b7dde1e47d1ec1ebf56d6937a87d36732a3891af35554a3f4ced1c5cf32cdccd4c9e206aed724e15aec8ebf78 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1224 Depends: libzenohpico (=1.3.0) Filename: ./1.3.0/libzenohpico-dev_1.3.0_armhf.deb Size: 244190 MD5sum: 38cfd5c8be484c748834bd21a3f93320 SHA1: 985cb64355c8c252f15e03768e30ba2ca5ba7aa9 SHA256: a2468e71f1d54bf3a1621124b48c87d148430c83bb8e266ca3d9bab1967a043d SHA512: ed69d44a075a76fc07996a96ee5e078207431d8e3722cddd420f173b4843ad10aad4656fb8696bec1836bfb7d31f77ac936ebd2e2fcb655b2dc0c105870f4a0e Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1449 Depends: libzenohpico (=1.3.0) Filename: ./1.3.0/libzenohpico-dev_1.3.0_i386.deb Size: 318308 MD5sum: 019b11bb1eb374838c1a6984eb4a202f SHA1: 58624df10cdeafaa66d01ec3a484df8c45f42394 SHA256: 9cca0ec8de754ee6293e19a8ac9c2ee1c55fa5a1045975d4630edf58ab310cce SHA512: 3aa67acf229c36e2245b5f9d03b73f6d262ce1c7139e3980eec590c581583ce2e2fd5d25dc6191b9fd975a76c1c51d6cdc13aacf3f70182edb2b8817fdd20269 Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1375 Depends: libzenohpico (=1.3.0) Filename: ./1.3.0/libzenohpico-dev_1.3.0_mips.deb Size: 276922 MD5sum: 61553ed2f55f333a54921c4e5d9ec004 SHA1: d1a22ed234d9c526a1b32ebf5e5101bd3a6af9b2 SHA256: 3a560e84c6f67dfb69c222338ee0f4ed3ba1b6e8dc69c450585fb3b62cefbb15 SHA512: e7cc96dd218a0d0d4e911c8749c38b323abd33a49510f9bd7d96dc3b9bf135a60595d001146425e2648c8e75d1269e1eddc4741f65ccf24edf24e0917268f4f1 Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 482 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohpico_1.3.0_amd64.deb Size: 176682 MD5sum: c7c578671809d15704b9bf8f4748f484 SHA1: e5f93ab2d099479acb391ae588ebe8d95f628743 SHA256: 9262b669ddd3080ef48e623e888a8c7a337b204fd9482d5d6cd48b1acfbfc8ca SHA512: eed21578a4319471bdd23491b4677a1940fe1db91ab91cc545e7c82708668f0ffc17b0f025e2cbe6583b320d48ac6406db7eb338e3642ba7c016f9abfee8755d Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 381 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohpico_1.3.0_arm.deb Size: 153296 MD5sum: fe48d6ae77cc5d9e15ac1fa879d88cd1 SHA1: 9d01f56672555915a780bd2e5896b57532ed855d SHA256: 8e007cb48c48ccf300da3eec3b002d8012cb6d93390dff83cadf0eaf3ddbc34f SHA512: af99c8e5c206fef0be7b90e72f18649e859af54773a0469a43b08922c34d03f388ddfc3cb3614c49b87a20fe0f43f0752158c59bf4e8a4adc21924fb39f16aa4 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 492 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohpico_1.3.0_arm64.deb Size: 174640 MD5sum: 238446a5810e93d5d131f1798a826102 SHA1: def2a7058ade3708ee5e95a41ad1c2ded81dbe9f SHA256: 5944827d0ecdc5941e59acea18c178b6e46fc67ba6300c5fd839ccdc3f3cc3b1 SHA512: fce9f7bb3ed1702733dbf4e37aa22ed1254ed093760e184ae3734520c03748664f0289a503b403fb5d6ddd12c6e36f1cbada6d7e8df05a8be555ebbd92fe00e4 Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 352 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohpico_1.3.0_armhf.deb Size: 145740 MD5sum: 332969f696c586699628d9cfcb70af32 SHA1: 78d6118b8307f13863f54d550e174ddacc081474 SHA256: 406e84ab732cc2a2cfc4614dbf7a20908668f5f928f2240aaf6c47ebb8de1934 SHA512: 3dd7643873c3a795a461f801df211d20a9d167ff56330991d3aeb147fcd80707b1d6ddc3af348dc24b265e0aa229f56cb4d2514d995e1d8d953bc8d91b0bd7d1 Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 508 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohpico_1.3.0_i386.deb Size: 201808 MD5sum: 829552bccca4d4d5a9dec9ac9795e3e4 SHA1: 54a1524a74181018bc09584b8b19f632f84c0d59 SHA256: b60a724aab7ac31fc1c6b6ec11e3e8f16868a6985fb76d48ce5245a1dde3920e SHA512: 0050214793737a5a20eaccd2f16cfe14c3910c43db7f6ff2473f25a9bed9f7be8c72843785753feb89552b3502d02774a5ebac58d4652f2dcb315bb50e9d4638 Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.3.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 461 Depends: libc6 (>=2.12) Filename: ./1.3.0/libzenohpico_1.3.0_mips.deb Size: 158886 MD5sum: e063a393580dab4ff47a53927e906645 SHA1: 0258bfd507da07489ff926f2a305277420efaae6 SHA256: 1ab7ef4a97e1b1498d27ecb0d0d1f3f1e45a7620de0fda30bd9a5876676888ee SHA512: fab4264b721226c12aa3ffcce2cb2b9b070579a488d348604722e6e810a44c19a4c3a619d11b45a41f9dfe8fab13df12f1375c10253fc7834950124a2cd9fb73 Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14999 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-filesystem_1.3.0_amd64.deb Size: 3860388 MD5sum: dc576b50d27a138f4d87604ee13b47bb SHA1: f8abcd83ea2aaed9e3d474dfb6b08e4b29444d49 SHA256: 344e1419b8ae356c5e2e4d26173cc88be387a3e58d19d332a46d6b83c396f31d SHA512: cb4e98de4c0193c1eee24a1fa3657d45f1beb693afc6d216bf49ca5b313b0b031fc17df23f54429b10350cadbf90640b76ca8cd901e51bdedf0336a7eeae461d 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14112 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-filesystem_1.3.0_arm64.deb Size: 3438320 MD5sum: 6da02d536c3df237675913145334bf05 SHA1: 05bbcaf96ea250f3cbf74adeca309226a62185b2 SHA256: 4513d05653a713e2a1752c6e4816d0128bf813a58950f26acf7e5016a33c632a SHA512: 830ff7240349be83d24ee80fe23ff27faddc72ebf54f733ae137cfde9fa85402337bb6dcc259c47dfed8577098b720a6bfba1d1bde1a612f5ee837ca8218f903 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13280 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-filesystem_1.3.0_armel.deb Size: 3395112 MD5sum: 5f7e6d03a09776cbf9d3c34838b77012 SHA1: af083d3ed9507c82589cf53ddc993c387f5dd270 SHA256: b792f7bb7793a1a3e7c81c36bfc8bf59d138abff2d12a51f4b59f10bfae3621d SHA512: 82662e1ceff1dafcd712271e494c9d5cb94469b678f214464bab34a1534f09954cbce0773e1cf481c00f5e15c718b2b7e1fbca9d6434573fc1ca440d093343c5 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11241 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-filesystem_1.3.0_armhf.deb Size: 3504552 MD5sum: 8bb1de73441a6e1a8525357365956300 SHA1: 41abfce9f350a1ec86e85f95c03953ff6e80f68a SHA256: 5d17a476155244b514b71e77fd1a20e8436475d65a15e78220e63d3de9e3926d SHA512: 804dd03d2631e26ae68537f512684a67e622e6514c7f27e2ec09eb100af807d59a5d2d3202c53f26b9a742365a9de8ef86eb958794b6c8ac8c9f7fba52f37913 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8062 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-influxdb-v1_1.3.0_amd64.deb Size: 2079152 MD5sum: f5b8275f88837232516019a7a37d4496 SHA1: 253683e0cf0e042233a6c11d8ad21c251fea3225 SHA256: 45ec15c8da5ffd96fbb67306f36a90c7d893be61aa08d96e91eccd962de73799 SHA512: 26df264adab94a367afb8cae2519b8a41990fe65bf8fbb2c5ef83d8fedc1176d3e4b361fece297ac4e7322ee5a0b3d02698d062884ccf138cb8cdbd72c351094 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8013 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-influxdb-v1_1.3.0_arm64.deb Size: 1900588 MD5sum: fc87f23317d35d463f8006fb0eb61dad SHA1: 2da1c58b66617a1b1ba36b5e3bdfda25b1935673 SHA256: 8c144eb44914e7ec0419739b4c06095e686780de8c75f6bd9bdb1bed2eae2017 SHA512: 7826be9c72da8d7cddb6661c89f939f3ad7fb5fd54e55ca41b1f3d60a33b3a483dcc891a24d771b649e339a9ece268258d391c78d5ee1d20362a682a11eea2b6 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7121 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-influxdb-v1_1.3.0_armel.deb Size: 1731492 MD5sum: 96b8422180d153e00a5bd427dd00e69e SHA1: 389365feb3eb877936b74070b096d4c94a5b5c30 SHA256: af2e4a7aedcdb153e3bfe6b927dd5120cd89fd7f2bcbdae95724a3dd5f958f3f SHA512: a53534eb6d9b452a27098cd6d941e32720026f2f2226e32780c1407dad1d7eaa8a6048048726620106802dd722522a634eb39086013b7fd338d6e675310613ff 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7017 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-influxdb-v1_1.3.0_armhf.deb Size: 1722216 MD5sum: 1d163451d593e848dc1516bb5d1b22a5 SHA1: 01cb50cdbbd3c5681df0c05bcc48173d8ce4238a SHA256: c72b5ca7289a1a17e49010191bffc5c75bb44baaecd93c0a8289279fbadd08f1 SHA512: 9ee2d63c98a95bdfa84feb2c14848ce88e2d038c7a033b27ce2ed7b05b88f5b3c76f36607af441a361ce0d874a7f753fe9abdd8736de1a92534e8ced9ddcd4cb 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10768 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-influxdb-v2_1.3.0_amd64.deb Size: 2794132 MD5sum: 7a215bb03537de81ede794798035fdfa SHA1: 10d109cc54fa9da3ed209553bef2df8fb18fbd41 SHA256: c884a3de4ccb902c50f4f5ef4495284f0dda09883fdb3a2e510c07d8c09435a7 SHA512: 3291eb51217f051d5607fd8feb759f3fdfdb0a5fdcbc576c0c9a91307357eab8b4c3868d5a914f180977604cbd174784035bcfcd777336eb5090ce9069010ba0 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10729 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-influxdb-v2_1.3.0_arm64.deb Size: 2600240 MD5sum: bdd9d5be29c4a02c970f30f958245154 SHA1: fb8223c523eff281ba49deae4f3f3a7af481ae20 SHA256: 4fb5ec3c521ca9fd4d19ead89913d80b77081889458a8b8cfac57a879ae0e7e2 SHA512: d640fee4e712cc488f790d420fba7e51a40f2b149b3421f3634bbe33a1182ed9bca272a3a6b23757005db9a447fa778f9d6a0adae107d1aaaeedf7796fd6dd2f 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9670 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-influxdb-v2_1.3.0_armel.deb Size: 2397900 MD5sum: eb37e3088d0f5e6ad47b96a2e3d0d930 SHA1: d031a075522a1f043f3097d636986a517908d429 SHA256: 6bc554cb57536140f705b1a7aae31eca7d9f37278b0f7b7e495442da0e6b2002 SHA512: 72a2692a901e4e4cc1856b164850702691b8611348c1026df03d8b1f0ed9a4525577dd258f5bf161c9e5bd9705782ab0d9557141a6ce1c64bb38c73f35aad326 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9523 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-influxdb-v2_1.3.0_armhf.deb Size: 2413248 MD5sum: c5a7f961a09cd5ea2efd4d49d52a517b SHA1: ea2119e17f6bba3e302a7af52c993ec178a2fd87 SHA256: 64b5062ed1d296719e2b70aa27e337fcbfdead6e3b02c198f83b6044ce010d40 SHA512: 40a220cd622f743e7fed1efe9abc1e6d27fca8ea7d53228449c2149779846c0f07566969807339a39f98e9097ba29b539b5936df5d7d40d13c68e9bce47c3f48 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13933 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-rocksdb_1.3.0_amd64.deb Size: 3635432 MD5sum: c6b661218163536ed1ccd831927fd451 SHA1: 07ebe7a86b7bbf911376687ed5a73e28e5ffc7e8 SHA256: 2e92d3c7f11127aba4cf45607d5a15cb538af181f079c251487176e8067e5d9e SHA512: c4e3823aaa2d3496e7e228071563e0e1caae1fa178411cae0924dd88a6d1ff566e2b3091a632e44408b17a8fea4d3d555bc30ff98ed07dd16a7470fc6acd1deb 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13053 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-rocksdb_1.3.0_arm64.deb Size: 3249052 MD5sum: 0934fe1b0d90bf97977f178135db3c57 SHA1: 6f344cd794badb86bac543c4983628b8cd373500 SHA256: 40a9b997938aae7888d2c1c9925f64d33cbe48d0452343e0b5a9625532527088 SHA512: f5023ef3a37d9669c4099effb7b696184fd14f06ea3ca8a019e1f767f207c7a0754ed130bbf498934de941f4375aec1d93e685a8d8c9b9efca5c59bec1095ffb 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12432 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-rocksdb_1.3.0_armel.deb Size: 3215080 MD5sum: dd4c502048d87760aecd97d84831f14c SHA1: 1a7f680d671f4872f0d89c3d00c50a9784966e7d SHA256: a06cc082042d8b5627c41f670cdfd7f970b546b7aeb785d06d41bc565f802d75 SHA512: c3b2ea04325768a41c83d4d2e065b4bc94120760d2978801199881f2d3613f5aa6cf15c2ed7c9c7e92f0be9316232a27281338712490800397ec8a543674a49b 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10357 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-rocksdb_1.3.0_armhf.deb Size: 3341116 MD5sum: 1e7cee0d7c44a46a0515a497398862d4 SHA1: 7fb125c1d7200ecd12580be241d98387636703a2 SHA256: 671d94c1408e624e30a805c674bff0519e6696e0986156f1c7cc8efb91b7e1d1 SHA512: 4ef77b72c3115fb9c40daa3726fac9b03eff9a7fbf91631aa05a2da8e91cfcf97b0d484f22487fcf52e09bc33f9730f5acb2bd306b225081e128664b16767844 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20348 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-s3_1.3.0_amd64.deb Size: 4425500 MD5sum: 61efb1ec813900a1f579a4333d7ab6d0 SHA1: 0369bbd3cc8c87296d2c9fb848ee9527ddf37fb7 SHA256: 12e2f4b6170fc6542afc3abb0b4249743eba029ac6113e6c708f33957a753a42 SHA512: 37baab40e97181e9296d82d8005b6509df0712806c9ec87374ae18cfd6a7031d0e5294fcfb5508094d7dbc611339fc9d657cd0ab2554043f2203fddff5c02c53 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20543 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-s3_1.3.0_arm64.deb Size: 4204416 MD5sum: 7a7e35dcc15abfbc65672d1131c8aee7 SHA1: 22df1310ad3ed4f895f8167a6c6ea2384c42f5b2 SHA256: 23e51d4b46eef5759ddfab88102284302407f6b3399970b2cc08bf3eccde3bcf SHA512: b74af3360ca82430ae82e13ed4c4f91627ddd9571bb23b2f6a773f1f8afd80872dab5116e2bfd41fc70d163a7587a82fd418554b116c16e32c96bc6078aee38d 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18968 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-s3_1.3.0_armel.deb Size: 3909616 MD5sum: cb8562eaffe39e2ccc7a5c0097ae3c0c SHA1: 5425a4a31131e03910b306dca7f4e8a3cec06149 SHA256: d929983a42e1b8e953c504a393c0146756183d98839612926043fde9b3a1ec02 SHA512: 5a42dce88a6a6cea2ab4893fd7eb88a38b1487295334ea3bf6f81ad5845386c8473a696b4773971cf63c03e895b7309e04eb7d3a3b5ea8e9ee63e7259b1939dd 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18712 Depends: zenoh-plugin-storage-manager (=1.3.0) Filename: ./1.3.0/zenoh-backend-s3_1.3.0_armhf.deb Size: 3942516 MD5sum: c30f1988619b41c379b0b6fa5b2f5b60 SHA1: e6fbbe392caafdfec4b7b309b23027b83610f448 SHA256: 2c76a21c1e5a4e621845c748018b7a6a0d4b70687b2471b428b4eea96e0a6960 SHA512: d64e147b6a52f2fcd93b853c603d0210c47dc75d63c8cd0a5fd6856009cf6e915736ff0ef3e937cc3063300747e514b29e8e52bd1a68eeddb8cb561fa91688b5 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-bridge-dds Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15807 Depends: libc6 (>= 2.29) Filename: ./1.3.0/zenoh-bridge-dds_1.3.0_amd64.deb Size: 4587060 MD5sum: c8f860b108a400713f2fa835d1300c94 SHA1: 55feca86703d8466627d89d8dbe403d4aae84ff3 SHA256: 6736e151ba7de6037dca77ac195165d978f52738af0fe91b393231dddfc355a4 SHA512: 45631438462e27f3b9fc15888d8e194f42d0eceb68d1d254c373730a00fcf4cb2e72468d9a4111c6d1d81ee897f87711036ba8614d92794e8a55321d4367b2e1 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14582 Depends: Filename: ./1.3.0/zenoh-bridge-dds_1.3.0_arm64.deb Size: 4100180 MD5sum: 74b3de2d407f7fc963f2cf063496c9b2 SHA1: 95dff6e95bca3ea1ab00019520afdf4407526616 SHA256: c8397f929790b7598dda52b65f7dc5a5b777cfd0262551d01506333e41e31a95 SHA512: 458d180d16d9a8ad1197b83462edb322c99d2ccc9bb1ef4d3c554ac9c156067907c07e73f4af9103d77beba5bbc719f3b542d9936edb50f67c8f560f997aebc6 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14961 Depends: Filename: ./1.3.0/zenoh-bridge-dds_1.3.0_armel.deb Size: 4183768 MD5sum: 8a8383847953d62689030d2bc8b85001 SHA1: 3c1dc0faf244bc3a0b9220101e5cba9d00e6a495 SHA256: 69d826357a992205f1051df56637c9b8682f5e28be2375eb75840ad5a2e2f22c SHA512: 84cb89ae0eef89f600d6b8b7e4a0176b58acf9ceaa1f556b31bae6bfeb156f41424767652fda5cac3aafb85f389e7c33d2e73ae6a32bef72bd6778358a85ab9e Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14419 Depends: Filename: ./1.3.0/zenoh-bridge-dds_1.3.0_armhf.deb Size: 4207020 MD5sum: fc0840633a3ff0576dc8e593e99183de SHA1: 56908cd988938b07e26be0c73107b320f1cc33ef SHA256: 098de13150dffa99f57d261601d574d4a6658b97a3fe365658e2890279c081b9 SHA512: 56951eda132c8b29079902df50809d40501eb97c5535d8bd828e00ec73333f751279d5b77ea259f26f91a4295850b904cf745230cb8a284a7fa7c7981838a6c1 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-mqtt Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15733 Depends: libc6 (>= 2.29) Filename: ./1.3.0/zenoh-bridge-mqtt_1.3.0_amd64.deb Size: 4274704 MD5sum: b1b3aa6dc17416795a45238bcd118dec SHA1: 9e2c8d37a5a03ea9331f941b4dd881e3c6e80b30 SHA256: ea47dcababbac9c4e9a3687c0a7d62de0fe3e82ab324ce9f9322b51665c3c93f SHA512: 51740ce84cc809e191381a74ee4a017122ec44735995e1ba0aecab7b0e9e8297b71001cbf23939de462ac0233848284bd091e40ae01c517ac11f5c243e47d4f5 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14476 Depends: Filename: ./1.3.0/zenoh-bridge-mqtt_1.3.0_arm64.deb Size: 3806232 MD5sum: 9fedf8ca49a708d7938887b28fdd3c56 SHA1: 757914ef65509c205637738c7918c9c1963ed87f SHA256: 38b44fb456f828b0638355fadf526f312c2d6479e6de722e9b5fe405148b7a7a SHA512: fc33fe932d83f267fd94b44dbb02f251241e926e0e8e9aa9df13f972b6dd59935e1f943b87be5f762cb01f98d71e6e732eef839214218b15f7879a389da5f536 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15060 Depends: Filename: ./1.3.0/zenoh-bridge-mqtt_1.3.0_armel.deb Size: 3915636 MD5sum: 3bafc01face5b7d00fc04b9e66c30db2 SHA1: 9d66e3363a4c01bb56901466466b99cf8cf7ca0d SHA256: 3d292e1e4a4370a06b1707e4f21e93022c4d9168662f526a19d29de05d08dc14 SHA512: a54ee9fd2ed1a9ae7b75089f207e9dc9e339939311ccf969c85713546e8b8e5d8a6a38167ad434fac8fec1d4f41f28560150f7dd26d281cfcea878e511844ffb Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14743 Depends: Filename: ./1.3.0/zenoh-bridge-mqtt_1.3.0_armhf.deb Size: 3911192 MD5sum: 0d2e53e4b5413d8834745c692c646118 SHA1: 7dcace8c24e6f8cac7ad3f30d17c6d89022adc9f SHA256: e517875822f111f6a8c1264cfdec588d3ac8107d1b2a9f9135c0c09c62f54c7c SHA512: 99855ad293afa3c0fdac5d4277d94905e22e050a9bf6882bf4cb640e894ca705e6244cd3b3baa02fee696039c5d5bade9d35e580396e95e42664faab1a697599 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16437 Depends: libc6 (>= 2.29) Filename: ./1.3.0/zenoh-bridge-ros2dds_1.3.0_amd64.deb Size: 4705612 MD5sum: cf1533ce27f4e9ba37a0c24e6844caf0 SHA1: 884dd20e6ee18fc1316446be6e424624e075aa85 SHA256: c4b7f1b5a44ce70a0bbea5ee278dfd127f4b15173ceb0d0ab6185967ea216e2f SHA512: e34cbff96f4fed230843cd67de19dfd130b2f634c32dfba0130abb49cb98accdb7bcccce239d404bf9ca87a4a1f90b1ec3e18520b832ea6b017808892857206c Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15136 Depends: Filename: ./1.3.0/zenoh-bridge-ros2dds_1.3.0_arm64.deb Size: 4212604 MD5sum: 72754b4531d53c89b43312f6d533ff20 SHA1: 69cb29019db7dd27456b385f4404daa7731a1402 SHA256: e4563b72431d1fedfb0959ece3c0782ad60ce4d859478e665b27234565658340 SHA512: ea9507f4028d256b503dd51a63f5333cfca98050f255f2fda14ae78e2ab69a667624d830e40c664269b4a69be536a6e8db59a43c0f1cc5e3441423cd126901c8 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15503 Depends: Filename: ./1.3.0/zenoh-bridge-ros2dds_1.3.0_armel.deb Size: 4302976 MD5sum: 6dc3f7a1d35e166484af5581ce12f6ca SHA1: 4c6a251b23bf985d86ce9048a493b1dc2a5bacf2 SHA256: 4b7ac9f6abfd2201535a2f9ce33d29c6b4029f212ee45593629b8621aa1d755b SHA512: 89fffaa43a8b8056e801b1e4994fa55cea124854b3e6cc4777cf15710b23bb8d93cb6d9dbeeec7a4c2ac3c87358cc92fa949dbf070faa0d5bd4359f14f77744d Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14966 Depends: Filename: ./1.3.0/zenoh-bridge-ros2dds_1.3.0_armhf.deb Size: 4320904 MD5sum: 9c7517ba9f8bf9108486494405838046 SHA1: aabfa16b1a088d9b82f24b250f1a2831206dd5e5 SHA256: b475b90cea66fc9b15925f9aae354588a40c5c3b398d7ef56e16e9a5faafa3c5 SHA512: 4b628a4d56d142c1df6c7ddbe156da6c7c729ca7485d3dc2b643cf7ce25e82a21798059e913f9e529e456e839bba7a8ae63c9ecfbd398f1e1e4484ecbdd9f48b Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-plugin-dds Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6334 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-dds_1.3.0_amd64.deb Size: 1705424 MD5sum: b63dc16f0fb362c204cb083bd561896d SHA1: 9458d712b19cc716d8270e646931d3a0d4b514c3 SHA256: 60688dd8e4e92bef2a310fffa4f517f75f36eb7b1ef40a217452be2c60265809 SHA512: 227297a2788e0c2da7d96c5e154d2732be44e6898b198af12f54e671d792d7c3d4f3e5488f0e629cda1a6276ebe1beac501452ac73777a6896aa6ac786e29063 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6240 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-dds_1.3.0_arm64.deb Size: 1552808 MD5sum: 8b7378fd9182e344b784929aa7fcd205 SHA1: fb6e31fc68dd066da59ed8d42d2bcce090bef116 SHA256: 27d71a7cdee712f149fe59cc65af28bf91c36c1df0305b00be7ec4ec03fd6cf8 SHA512: 15cebdf6e6d4cf389fc833f04f09f6a1b8ad68eb01ac856f6a4dd03815832e16c5c979f80200dc6222df17925308e2735d1b65174794f9af595e813f3efeeebd 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5810 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-dds_1.3.0_armel.deb Size: 1558644 MD5sum: 4d369084fc49c84d3c2534e5cbbabeeb SHA1: b90e56bb77458f2ee2e4c5a38151b9d7ad7f7fcc SHA256: 14f0128cf19c1804f001dbf60e004e879272c92c88e7b59c957c97aa7e97794e SHA512: 7279f1a4d60d23ff8acd7786aeae5b3e220b1f0eb506108d1dcc074612b1b359bd8a6b7f485b27cdee11c33531385a7d20b4682746e79b85e25a428c632c6456 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5468 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-dds_1.3.0_armhf.deb Size: 1574028 MD5sum: 74ee27b94b9694cbf456a0300b7e7f2f SHA1: ea95590f4b2778ede0761791141533986d6bd68e SHA256: 1d5d685baaa2b11681c6ae4d8c4a49dace73eefdff1451f1bd62e68aa1415657 SHA512: 117bce156f4990fb5182a10346e4e30c5897abcadc05cdb1d39a5eb53c26135ebcb85a3035b7733405e3cd65d72b3205480f110458881e4326a496fdc242f9d8 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-mqtt Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7672 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-mqtt_1.3.0_amd64.deb Size: 1920936 MD5sum: f347bc4698697f2e661f535a9fbb7b73 SHA1: 2f4b6b1aaea240f5c8249270e681db61e108441c SHA256: 0f523ad56ef02a59552fa6b730612174c3d7db2562d877876a00f3e19e54ea72 SHA512: 8b537aa60397ff5a7f68bde89640577305790378a3a1ebf219f70714be724a6c435f4cc97eca8bd9cb70fc49cc3dd254eb7f3dac4a67da13772bc6315350a4a8 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7421 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-mqtt_1.3.0_arm64.deb Size: 1744772 MD5sum: ebd89fd61b225e427cac404265820f0d SHA1: 304ed9a51d13be70d5fd0422baa156370027410a SHA256: 1978d102a0447e40fa2a90770340212d7842fd9172a3ef4e23510a6199ba2e1b SHA512: 560031f904eae8221346d66f6990dd0196f06fb82ac00869c606048c32efc8a4beedc36df404a2b174a7995dfc38b8d46a42d0afc2d14b8a51301fa89f33c2eb 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7058 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-mqtt_1.3.0_armel.deb Size: 1632628 MD5sum: e1055e20036d0674a8db955b84c5df57 SHA1: 664cff8ffae3a50ad6768a57ea6f90c31ba5bf36 SHA256: 9785ba835a3f54ccdc2baf0afcc1a91797d1f679253326f59f2a3ca68f1ded10 SHA512: 1e2db85ed0477423a43f157fa44e4c0c3053c67fbcaf78e4c2002c62489afa5ddb42562305d5007f3cecc36ffa8250ab21f2e992dc17b28fb25f4caaf0b712d6 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6893 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-mqtt_1.3.0_armhf.deb Size: 1640704 MD5sum: a045c2983aba5fb7a98e6f13f6f9b3a8 SHA1: d75835414f39197092a77a907dc589ec07c21c24 SHA256: 3550629dc553f901027c0252490ff0177b913b399cf9e6f83a312d2eca29ede5 SHA512: e6991cfbb518bf315cfd971b34eecd331a3d02a38243f788ee7bf315a0f7828c09899f56fb43e10f7506a7d59943886bd857dc313661fbc92b7443459fc70d41 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: . ```raw 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/](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](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. Package: zenoh-plugin-remote-api Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9886 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-remote-api_1.3.0_amd64.deb Size: 2490684 MD5sum: 61deff7aad1bf35d7bb56bdad08e539a SHA1: 5a26c56c09c575dbef17f0956c12bb433d896f46 SHA256: 85677534181015baa8366d0d38b1d0d992c6dd58ab71bfe30a04043b69837bff SHA512: 4f75c08cf93476b832a342c3807b68cd917a80dc5109730c3880b12a97a4d5ca5bfff88120664b70f1214a83bb7405b1a3521178951a9dcea99aca8a49ce5d66 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9885 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-remote-api_1.3.0_arm64.deb Size: 2306656 MD5sum: 454d7222e4df195cb3ad3d3d5b20777b SHA1: d817273d98acd5809f7a19e0e5ae390b3303c4f4 SHA256: 6324f093764ccaffa74008a93abfda0906d1047c7c87f38197fdf422d9d892a8 SHA512: 7aa60f59a47a44326218e48f89cad5096c19756955321bf6adef83e13f1113e0341d97e6d971b4b261cb3849b4e0cd001872efe4426668d46fedd4a104b9035f Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8897 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-remote-api_1.3.0_armel.deb Size: 2081632 MD5sum: dfd6bd715d114c9b943acb60feed7804 SHA1: b06cb93193faca71056606a185ba2f4238a29b13 SHA256: 635b6dbc18177f798ba290e72ed6e5177670669bd28d56d4f0bb20ee49327b14 SHA512: f0fdd11f63b88c4259d31d783e91daccbc161ed3b235772a35fac3b1ed2dd6fb00223d06f90373990e112ce6a3f9a7b77e2902a5a04224ec952d60e48df35fa3 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8724 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-remote-api_1.3.0_armhf.deb Size: 2090624 MD5sum: 8ef8ef65f3d9f14cc21bbe198c53089b SHA1: b94339de65a7956d310371f433162bf292592577 SHA256: bba7fae8fada6fbfb27db9738acd0007ef72d843eb82d5fa9ec58af2c591b6c8 SHA512: 6ad78df18b4fdda8f9f2da7ed3edb41d59c10ee4c8e7817059388d8d9238217c711ef3d5302cd34b53593bf11947b080d6fdabb06979f3bc4e9da31557bd9310 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-rest Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4600 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-rest_1.3.0_amd64.deb Size: 1236348 MD5sum: 4cbe79209e5ac2a7303a8ea0adcb9711 SHA1: e996fab3a9a2047d62b75095097bf051cd6c568f SHA256: 5427f4c7a6d626c6be346f734013f261480efe243b7c70189a511a1a5e3d013e SHA512: cc5dd396c004862d36b0ccda8f207fc2fe3a75a8dc0c16e6e5406a16ecf45e7e6535f3b0666781dd63b3bd441e1a3c69c8d51aa93ee192458f66099f76822c18 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4642 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-rest_1.3.0_arm64.deb Size: 1144688 MD5sum: fdb516c4e6772b2d25f5281e1eebe4cf SHA1: f6052670dcaf6f74f863fa108c284f702f167e20 SHA256: 7b864ad0fc9a3e4820ecf58e150126df756a9676eaf86636679aba3e79355507 SHA512: dc5a8eb654ea168b3471a2906270a23a9ae2e842319ae9e7d9a04fa4d9178769f0a36d1a5bf50bacb246b8860bf2573edb78d3df0666abbddef9e98c139921d4 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4365 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-rest_1.3.0_armel.deb Size: 1180672 MD5sum: a330e52fc13a3eb5ab7b87e696a9c668 SHA1: 7649321b94aca145db3a18fd5f3b0d6c1d599a45 SHA256: 2700f0478add73d4f7ff340521a74fd27f68508404c7bebf20b87bb5575b63cd SHA512: 1bee86a50ff229b64480774ee2a18615b067f5e7f8c50e43a9a9c3e792a680386bc8e0f4c6fe0eb8ba2a28899a7bbe92dd1a387c57a21335e6544a8a7703309f Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4296 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-rest_1.3.0_armhf.deb Size: 1175164 MD5sum: 864a5d38ecd5c12d35e4d79ca3dda2b9 SHA1: 9e164ca6e39690ac1d10f39fd51ebfa65dd450db SHA256: 835c8ac9d2b127f006f034203128a58be8195db1f62b6b07ea09c77964ebee7b SHA512: 4e7a2c654c3e313fdd48f3f6902c9da184be3d8f90af9c0bf3334325e5e9abeafc268f31a4b8a5e60c71dc74f7e76779814f90783388a6a6f1798105994040e8 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6894 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-ros2dds_1.3.0_amd64.deb Size: 1809272 MD5sum: ebf0d85a7bbebcfbce661afb9b995a9d SHA1: ee35f909f18c090ae03536af56cb7d2bb0225dae SHA256: 25d6bda8c447b4f044241ab1e2beecffe0d95cf66b3123ee96a9059bcd8ec07e SHA512: 4fce9237668fa152beb311b61f6a0ee833a3bb1e40d05badd69f47e5ca2133114e8a5cff1ad56b5f2b72eb2c990c5a9f51e763ef07d8c5556ac90f6d7bde6ceb 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6739 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-ros2dds_1.3.0_arm64.deb Size: 1646700 MD5sum: d80d9b3df34659a889e91a9dc576e20c SHA1: facbeb4a61a480d8604810b5d2792f5a53471d4c SHA256: 11f179e7e951e522d779d01c58afd84837673dff57873cb9707e068c3953f7e2 SHA512: fe4057b7ffc4b8d4f0dc9d97677f92d04b0cdde0071ee4bb46d6caff7b02625e622a1c02fc1e70e2f5819b3715b56d62c9355b9e15b154889e9ae2b691702ee0 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6317 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-ros2dds_1.3.0_armel.deb Size: 1664184 MD5sum: 841636c3df6f42e40507566c537e5a68 SHA1: 75c8c6c3c944e581560c27678da4e68ba5bab155 SHA256: 8ef8a4d41bbc94ae7162a99395415c1490047275e91c877b49e2131292495315 SHA512: 1d851dd665b656ea91d9a9a83944ea7cb54e626c3452c60d14af43813640230a81272816c4eca18c85483f758ecabd244384e09a85179671467a25b096f3de1c 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5982 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-ros2dds_1.3.0_armhf.deb Size: 1685576 MD5sum: 38c9758fa74f2b4167bf6e109403f285 SHA1: 0a81ca3f782695e25fff75db526265494df11d20 SHA256: 069cf2c6ae4a9acf86ddf7ddb4eda7e69c9e14978b17d11939817e151921c73a SHA512: d250ae0c62adf4e2c55cfd6b383cf296a84eb6a2e3dcfe2264acaa535c694adbdf629ed760132f5d3a1fa9b345f3919b46e1becf4b8b0ac0477f64c047835c32 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4335 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-storage-manager_1.3.0_amd64.deb Size: 1129180 MD5sum: 89d55cf8eec59a61e50de8e489f64b43 SHA1: 9ae9644001e9a3853e4d09e40b2104c5ff82edec SHA256: ea64a1e1ae31489567689bed14da86bba61a56f8f6d7ac13ad7b4171fb79ff3a SHA512: d43978c66bbf52a459ca0119959f821d0cfbdbb3e752e39f7b696f49e5963556d3a5a4e6cd885b92578de3b13b0df91f40ac86fc7a2ed7d122eecf6ab16dddf3 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4363 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-storage-manager_1.3.0_arm64.deb Size: 1047620 MD5sum: 9c1854faa095d17f9b27780614170d5c SHA1: 704392ab64c3375a24b5436dd2ca1be0bfc4827d SHA256: a6d5e3bb9a37e3c842169006e9238a905b7d93cbb7d0358d1f336770ce1e5572 SHA512: c768d28bc500278525b652c86725fec37d2030c77772d5ac6d92c72010516ed763873f46f7272276861607ba37efaff5a0fa9438926819672cbecb2d9e24754a Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4115 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-storage-manager_1.3.0_armel.deb Size: 1095100 MD5sum: 87cdd87eca5185703e12e32445d967ce SHA1: f04aaf713fba0531a1260cb3a0ca39f5c931962e SHA256: 1763d88bd6f04ccf4176d498a49146e10f10d39213f08ed7901f5ff6835c8070 SHA512: 67b2ec10602b9a11cc640757a8f9e85dcd545963b55e12487fd336ef32f0ad54616cd6afdfdb753210813adce55ccc41ba683305763eb46227aae0bddb39ac4e Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4026 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-storage-manager_1.3.0_armhf.deb Size: 1088804 MD5sum: 50e8e2114ba95b37160d28709b02cf2b SHA1: 099985d6b9d95143adfd6ff3b2c93bda1bed611c SHA256: 61be1125c924084820b928ce548e334fb9a737d6490d87abe4fa7f653215bf8f SHA512: 3f937a805049d81ea6d68b1ce055c8e42b27ee8280bf4fc1d519253864309fddba4b3d5bc2953893f4ab80bee69efd8238096b06b2168f69791b9de432bbc954 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-webserver Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6962 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-webserver_1.3.0_amd64.deb Size: 1654632 MD5sum: c88c70e036bffc8430bfa9ffa95307db SHA1: c32d73b9a694509e8d07a395a806fcc911af431f SHA256: d5cf562eb8b6594215eedd765e648799d8ec928032bad47e6eed13360a02c6a1 SHA512: 552355768b5f2ee40151f86c86b13c7524f00a5c4735697d82e83b180caad9b3c03ba5fa57d74b0afa83a1b78eb9b52bf9df6cb0e748299ff1f1e7b2e59ca39b 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7176 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-webserver_1.3.0_arm64.deb Size: 1550084 MD5sum: 108edb1e80c15f642dc9fe4d0fd80c53 SHA1: 2e39fa474e61419ef103d9ef38adf04366db8725 SHA256: 5545ab17ff4cc295211e0292bf5d3445fd97993ebdedf6c8a3ed96a256201303 SHA512: 0901ff8236c006206f7076cef877090ff30fd9c746318ad8c42d1adc0c38c3972115e828415ee88741b00fbd06a85314f9e24be00d59a07b097d366fa0bf9c4a 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6499 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-webserver_1.3.0_armel.deb Size: 1526200 MD5sum: 49967bc59df421172b27a7c4b26cb724 SHA1: ea8027a67580b5b7ef0ce5f98ebe9164d65b23af SHA256: 639ff3ecf7671bb4e1db10e88c2d87666f373db6047709cc97e0d68f4a766d70 SHA512: e1b5bbf3870a070314ba602bb4e591adb56700618b3977ec65d121ef7f5a9b08bb1876c903030a662df39d4228475b8a2909ab6aa04dfdb5b871ce080e8061aa 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6391 Depends: zenohd (=1.3.0) Filename: ./1.3.0/zenoh-plugin-webserver_1.3.0_armhf.deb Size: 1522632 MD5sum: 732cc759065bc588870e38120b3fd5cc SHA1: 8bfe5b791c45223c1a6aa78e30c239f956c888e7 SHA256: da4d343c6769a026ef14a8538d4d5e8557e411c9f00f752d7e7c9448c0d7c0f9 SHA512: a975f1ebe482824c70a4fb152c5684f9468a142d380153bf53fb691efbbeff426f9ed2d38f222ad5eebb72e21c7b1318cefd71e219c54556a4cdfaa32c7a97d7 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.0), zenoh-plugin-storage-manager (=1.3.0), zenohd (=1.3.0) Filename: ./1.3.0/zenoh_1.3.0_amd64.deb Size: 17548 MD5sum: cc21aed83f3ac29117e2d6c6b7844fee SHA1: b92a8d218ba648e633786e0cea716000a5452fd3 SHA256: 164f69c4ca86f746c05a407970b6cd32c89baada26018c561b883ed9d44f6b14 SHA512: d62b1f2f0b61fdb497c5b44040fbe31bfda24adb5fcd2b9abfb340b26ea5fe01351de7a7de9edfc354a1580cebd77e7aebb5f5fa8c2ac18d290c86e905d58e11 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.0), zenoh-plugin-storage-manager (=1.3.0), zenohd (=1.3.0) Filename: ./1.3.0/zenoh_1.3.0_arm64.deb Size: 17548 MD5sum: cbe28a6fa596e1b23e3650dc34d2f727 SHA1: 9883d400d30cb9b968d8af82744df5187934c54b SHA256: aef5bead11b073b4e0d753ca38874cefe74a86b495bcfe5202cf664216f7f3ea SHA512: 9f807f54b296cc3852ced1137d23703136639068700febdfe3bc1398c9b795ede8d7eecb3396949b8bc665170ff7732a8cf83e684c8baf3186369857496da27d Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.0), zenoh-plugin-storage-manager (=1.3.0), zenohd (=1.3.0) Filename: ./1.3.0/zenoh_1.3.0_armel.deb Size: 17548 MD5sum: 98c37e932704dcc376c0269053293758 SHA1: c5486f6781230751ace9acb1b2aea64510cde620 SHA256: 98099d2db77593af973d9d2c370637771f8a5049119628377cf2ac63ed2a1877 SHA512: 4165ebbd2328f29b378e7feab656e0072261966b38971fc3896d294a5d7d474c5c93139167decd5d32d29b5fe67da73a4e9fb66842273c3f71037a1572e08822 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.0), zenoh-plugin-storage-manager (=1.3.0), zenohd (=1.3.0) Filename: ./1.3.0/zenoh_1.3.0_armhf.deb Size: 17548 MD5sum: 7cc965369b0cd40877e9da49dbc4d7ef SHA1: fa9f72fb141e91071f6615e7ff3b1ee3341002c3 SHA256: 360bc97120007ff935601c3d68dbb3ea8eeab180463fc0ceb0ce7b85bbbe1c36 SHA512: 0b803045ff730f9a4f55127e8b0e8468659a7fa152ce8ca68e54b30bb2c129a743111900d11de713d626583ef74771aa67fafe359c59075d9a9e09ec421facfd Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: amd64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13504 Depends: libc6 (>= 2.29) Filename: ./1.3.0/zenohd_1.3.0_amd64.deb Size: 3770816 MD5sum: f397dde0a3ba286091c6e7ab9b17f8a6 SHA1: 6911e1eafe1229e78494683d44cf05347781e6c4 SHA256: 29cdf6b7ed4cfaffcf74748e870943cfba42a898f4448ed53d639e52c4e9b17f SHA512: 8d6d729ad3f5d380fdc7e123cfa1ada02c33a8e4a23ae034c09d8385887216691b94ef4ac6d3e2e02728e91ed9e2295c40939492dbbf9cdf293aaf962d8b8634 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: arm64 Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12221 Depends: Filename: ./1.3.0/zenohd_1.3.0_arm64.deb Size: 3370244 MD5sum: 84d71964a564d53280785b19693664d2 SHA1: af39cc43ea537b690ef2bcf7e0e329152ac35629 SHA256: cabde56e0d63db5108c5fb57573c35d89e641e0c8766eb433bab1035c7ff8d9b SHA512: 028562ebf23e4045f5f85f34fd7c02d08e2d9cb09743e06da1cb584fa2b3fe762b306bbbe4a76e189f9de60e709452fdbd6c078d459b6258cfe990c9d37ed025 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armel Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12851 Depends: Filename: ./1.3.0/zenohd_1.3.0_armel.deb Size: 3526152 MD5sum: f9aaab0408972f86d6fc9681fca2d88a SHA1: 5b17f586ed2a9fb2b9a27c309421b9d9cefe641e SHA256: 4dd7c59782e457ef79936f0f1943682451538ceedf1df4bbe6b672b55f735fe5 SHA512: fe412cf87fd5b16e7ce91dc4d7bbebad30a9f539b96e0ab2a7054f2191c5632b6dd68c975ccbb151ca7a726004d3fe21c20d77e238d65cc58d8c6725cc8de585 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armhf Version: 1.3.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12578 Depends: Filename: ./1.3.0/zenohd_1.3.0_armhf.deb Size: 3546656 MD5sum: 1dfadbb9abd17ea11ff4183d8751f648 SHA1: 3011e7bb5530407beaa0f1dcabccd725046836e1 SHA256: 9ff2d8ca2f610a3b81d982f9e386aad4ac1e807f2595da42044a0bedff7dca34 SHA512: a4c5ae9c2738601765d291335c7c2f0e3630eaeef9265a982c662532ab629f1541e5d3972689e40940a3c13e66e120ed0d7912643eab19d519fda4d7f4069e6a Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: libzenohc-armv7-dev Architecture: armhf Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30835 Depends: libzenohc-armv7 (=1.3.1) Filename: ./1.3.1/libzenohc-armv7-dev_1.3.1_armhf.deb Size: 9550702 MD5sum: 4035f078b63e4f1a4853cb2c96660b47 SHA1: febf36f8eb58e49181d2bd35282ff672bfaa6c7c SHA256: 8d4d9e8de14261571859d60feeeceec1b349991617c38d6737f98f6d7bb76191 SHA512: 2b0a2ca7b3fce43b0a2fde7a450da17d3e52de5462a4486b963eefeecec3d8ef679c5c8775f7333fabc6ff3ce80221c033391fa2c28381c598db9d865f95d7f4 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13542 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohc-armv7_1.3.1_armhf.deb Size: 5687834 MD5sum: 0aa2ca0539c4610bf6c59b1a298b964f SHA1: 1d1635a7c03d71b81ec623c00741697a42b33504 SHA256: 1306b049cf5bc651d708d02463631318877c29a30cb3dd107d4e52ffc6922117 SHA512: 2c861e0939c3538f8372052d09a83666a0dc3c3d12d2ce21b3f9e6af28e91a635c1ce0deb48b65c5c175014fe4ed3a1822b318d53514f71bf4c391b311c88acc Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37436 Depends: libzenohc (=1.3.1) Filename: ./1.3.1/libzenohc-dev_1.3.1_amd64.deb Size: 9162234 MD5sum: 92ac4e7190500217a78cdcb4d3cc19e7 SHA1: 1a60e71806430fa27240785fbfb9335ef70c0d31 SHA256: 4f2a0357cf5b98665e66e52e99e515e061972341a7a84ffa36966ef42a880ffa SHA512: 0ff5e0559296e56500cc83c851404d848684356a61aa43b137a452e3434b701e5650243ce5224af494e91f67e25f5b05ff851ca4293b3dcc4019736593607580 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 36783 Depends: libzenohc (=1.3.1) Filename: ./1.3.1/libzenohc-dev_1.3.1_arm64.deb Size: 8837938 MD5sum: 26ff254734b77b43291f6daaff931eff SHA1: e8f1b2ae79f7e5f178ef9303932626fae7cbfa29 SHA256: 05537fbf1b34f43fcbd457e7b3db0431f80de5a1a38028830704748d0322110d SHA512: 871d6d53841bf62d0877de6f7fa1760d159de00c671b02a1a53d81291355d3475d599cb7ad217a2c5b85805dfd923ab361e005acbcc2d58cf05211571a5821ee Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31017 Depends: libzenohc (=1.3.1) Filename: ./1.3.1/libzenohc-dev_1.3.1_armel.deb Size: 9616796 MD5sum: 5a106c1e91a320211046ec840143c81a SHA1: 1805920a682b5ac7518c280eb3750e30285ac952 SHA256: 5ebd846a886d0ef305a6f965a7e86d525ef7823dae5786457260f8d958b33b8f SHA512: 9777cd4d39df2c05fb8804fcd308c79c3997fe76c3a47675cc8a095a198b4d15e8c5e29d9f68cd3b125ca409e5462e6b8b04e29a39900a7375b27c7378a883c1 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31162 Depends: libzenohc (=1.3.1) Filename: ./1.3.1/libzenohc-dev_1.3.1_armhf.deb Size: 9736052 MD5sum: 28440057be60102793e44d9c5743e5a9 SHA1: 811f0bed15ad6e793085af57d95ddf4fb460d4b6 SHA256: f6484a38877cb29336d49d1208411b8679dbcfd994dfcda57f4cfe769e1d52e2 SHA512: 16087da0a46c9328ea7b2b2bf0915fd8e3477afdf54f3b908dcf61845b8a2eb22c0faad5a965f96d6bfe5e6cd92f2efe7e5196d402c1a96ee5b9a357e8585c88 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 35211 Depends: libzenohc-musl (=1.3.1) Filename: ./1.3.1/libzenohc-musl-dev_1.3.1_amd64.deb Size: 9040152 MD5sum: cfe333496d33e554937a8c44855cf925 SHA1: b6e477a1fb27b0019878b9b6fab58f307be31fbe SHA256: 559913ac4a08a707a3e6d1b8eb6285a5d59b8d3bc874fc844678a719be96cd06 SHA512: d2d9333e19b5cae4e0387ed4c7788c79b63cc7c17c1159a9123bb59d1f7d9a3e0a0a59ff4a41f85b28b4a701147d4e1a43406b59d907941c449302f9d7a414ce Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 36088 Depends: libzenohc-musl (=1.3.1) Filename: ./1.3.1/libzenohc-musl-dev_1.3.1_arm64.deb Size: 8703680 MD5sum: 8625c78394a36f4da2612ddc664c44a2 SHA1: a60fd4d318fa0a2ee25c789002e826a0607e0aa2 SHA256: 33108664f5de1349e1f525431609e394625282327d1e0a04d4f51df20a488b0b SHA512: a2518ad84371619782fec1560c35ea272ff820183056cf5bd1a2697c92ddf58f2001948c866d8df738af2c3753636d6aab6f6ec0f142bedbb5eb2a85df0b0e82 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 14404 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohc-musl_1.3.1_amd64.deb Size: 5711890 MD5sum: 49d8e320a1b6a3a66423d3785ee949aa SHA1: a4b8dff7e26ddbb9af58841544f132789d72d9a5 SHA256: bee1b05aa7f44109cf74001375d0edcfa34e5638472df8fbd37c5174d524e05e SHA512: ef72f6a27a31e9071abfa32fbd2a681ade3c08964c5593eac25069d1a35a38f9829114b37a9226687dd812128b8db5a7347d7d2fa362ba2221f78918cef75b8b Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13433 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohc-musl_1.3.1_arm64.deb Size: 5426934 MD5sum: 2823733f64906d19306d888dcfbf02d5 SHA1: d8c5e88e3844ebbd91218384ab48cde716c22997 SHA256: a23ef90b008e3c2f0476de8e587799fb3931c37abf10cc9c85f024610dcd738a SHA512: 1c89cfc817f6947269f64df9014c16f3d16eeb8cf7ac4f2dd70a5edc66d433471b250eb76f61d703fa986bf825482d89b019df8a2f3a05a746d670f3f04c5150 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 14410 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohc_1.3.1_amd64.deb Size: 5709394 MD5sum: 4683ffaae654e2ae09574286450261e3 SHA1: d19d8b42d1e91eef6169b46830213d75f6d29bfb SHA256: 28a8f0234e9031153a7e4ddedc87aa20307ffe371330f8bb20b818b976c23bbf SHA512: 095e28608171ec54c101e147a5d1f1b4a20acd134697802665af420212f9781e492a75385cc1645afb26f4a905e54c026bd4255bf036d7e4839106860967002c Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13451 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohc_1.3.1_arm64.deb Size: 5454354 MD5sum: 230c5489b911912ef27ac1ebac5c7cab SHA1: 21c697ed0a8727e394e796f26d2cf0f9b1afe1e9 SHA256: b546519767a1d352378379b8d8ad5b836821ec713bbfe4448518e7eb5ce18bfb SHA512: a208ac1ce40160f4dffae68bf2b9373de3ed2b37ffd6c5ef9e15cbe934cc663471bb356dac974b019ffbd235781a7b081ebd129dc4f65c2d0f0633165c154531 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13790 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohc_1.3.1_armel.deb Size: 5760064 MD5sum: dd762f45be82df6e2149cf675f104323 SHA1: a62d2fac7cd5461b3e7c2161f879d32a00dc0d97 SHA256: 9ff70d987d2f299af94aeef739791ad2cbb4d965bac7748400f4da35d414bb14 SHA512: 9e1a7c89d42cd29aa8a416f1022af3c3b6b78761f52a0cdd5630e59a8c19892e36ad6220a53ccf400118657891fb0f9cefa3a85d956e725e9db87540d8fc0cbc Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13794 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohc_1.3.1_armhf.deb Size: 5834420 MD5sum: 503dee350227491b4d93e36b1aaaab4e SHA1: 5dfdefc8b1ce40e88144ec365f4eddf18ea47133 SHA256: 15647c3e2148b1c84caac5bbbddc3fc3bd353c151d85d7d96183542746e9c7bb SHA512: 6203727ca38d45cc03e9b3e11c21c637147608a2c71b783205213bf8fb4b814de8880d9bf137adf4a91f8d27514967906c9aa1f52ab84fe07292d36499c1bc9d Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 448 Filename: ./1.3.1/libzenohcpp-dev_1.3.1_all.deb Size: 57454 MD5sum: 068951b703391a41ce5db844bc5b922e SHA1: d5ecb2bb74ea0beefda40303067aafaa16cce0dd SHA256: e951749a0e8f6f23d6d51dd90615f4bb50624935819cc84b8733d58212bd8b97 SHA512: 111ba2da546ed07cdde260e7c88d5cb6b09504e5387b626eedfdf858337871de83c7f4b9aabdf460980bbad72e93ee5c0633ac9e9be37fc4dea881524b31d890 Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1251 Depends: libzenohpico-armv6 (=1.3.1) Filename: ./1.3.1/libzenohpico-armv6-dev_1.3.1_arm.deb Size: 252332 MD5sum: 8326c3657f4c20a353d07115a94a93ba SHA1: 7a1b819f6ebf5eeedc4116412aa6d55805fd3a5a SHA256: f300b191521152b65faafaf0f9a2f863f922ca0482ff8056675894058910e0d4 SHA512: 6b72a8870d292ec10888eb83c1daa4cb359c2931b997206970e38d966f967baeccfba13476852a46b15d5b327cf08573f3f0fe1ef69b6792f35b80f1c807eb3b Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 364 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohpico-armv6_1.3.1_arm.deb Size: 150116 MD5sum: c2a06e2b8fb3689624c37f5a99c8a36a SHA1: f6380b1ebe43bca9b133add58a35d376d9bfc8be SHA256: 24c5d05893f81a7f6d7d3caea2a0c724b673cad6f21cae75e4ad90c228ea0433 SHA512: 8b2c750cc8b8ad55e8d803a266c8aa9efaf95edeaf4348cf620614b025fffc0b613f046442776706e1cc3607b1af2436c231142bacf421d3e66f2670b341379d Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1243 Depends: libzenohpico-armv7a (=1.3.1) Filename: ./1.3.1/libzenohpico-armv7a-dev_1.3.1_armhf.deb Size: 250548 MD5sum: 1d10893abb88b3c879fc5e35acbee79b SHA1: d728fdc1c2a2c87635af3ff15f5854cd98d8192b SHA256: 3297f2e081fac66a721fb1f943f0b1efe89f4e084f14f55d39b1145cae297c6e SHA512: 33b975700c1dbdf496a60e91e70dac9c8fff1ba8564fbe0f4f9ee5213441e8e2c8501eff3dad5c6d6d5513c15d9941280684572489a0ce55260328fc943c7b26 Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 364 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohpico-armv7a_1.3.1_armhf.deb Size: 149320 MD5sum: e03a4321f7ce660b6eef005410490508 SHA1: a49c113c049c184af28a74f63662a966d4c48a88 SHA256: 111a842a1485f9483e4ddea418931237e74c6d4e750c258e51f8f33e94e0f2c0 SHA512: f3c86b1c5971a08c8c79c3db646117e4dcf6daa69022322eac7ebfafef17ed7c47bc46dae043b34820e4b411e0306719124bf4bb2a1baeccb7677bbb592f2f99 Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1505 Depends: libzenohpico (=1.3.1) Filename: ./1.3.1/libzenohpico-dev_1.3.1_amd64.deb Size: 300278 MD5sum: c0a3fc2441c9c34fae2b3a91ea6e4f11 SHA1: fadceecbe66d0790cd9441852da08a557029c0f6 SHA256: 9b8fab3624027e52a87cd8aaa06ba0d0a57792b2403bc999378dc0195f40d8ba SHA512: 5caf7b41e1621e9f95ff77273f10d66756872c535ccb4672861c94c57c487fb5859ba548268adbd803d5e3c70a398dfe8c6faa028b92cb69a895a7c572c94945 Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1250 Depends: libzenohpico (=1.3.1) Filename: ./1.3.1/libzenohpico-dev_1.3.1_arm.deb Size: 251780 MD5sum: a3fa2c16171c6301f3723a11dc49937f SHA1: 17c471af3de39e633cde5a70e48d5a3ef12286a9 SHA256: 8faf4f6e6aab24ffc9331e0093190d17954fa678d8b51e67be5683e57e26bdb7 SHA512: 6ece62254fa44f2e03ebe90383843c53a63ef30280f5d4596f9a29618a92613291e274bb4b2ccbe65c63d81c05a2a9e0385cfd09031daae47866be873688353c Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1515 Depends: libzenohpico (=1.3.1) Filename: ./1.3.1/libzenohpico-dev_1.3.1_arm64.deb Size: 296676 MD5sum: f41b19f400cf6b35fffa48b7c826750d SHA1: 4bc354466b675abab4ed58c4265e1100aadf6135 SHA256: e3c79d0a758454a2896fedc5bbcf77e012af58120d8c0f48c4967823e1056342 SHA512: 10400250c3fdee323993ce6ceb4e1f231a2894c1f721fa4f40d940abdf36fe808da90dbc044399a4eadae65441c609b2a1793bbcd32a59bd3025a50f8dd2b313 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1244 Depends: libzenohpico (=1.3.1) Filename: ./1.3.1/libzenohpico-dev_1.3.1_armhf.deb Size: 250264 MD5sum: 0f5f985ff320abf5e4f1540a9b463bf5 SHA1: 355d93d4eb8beea921b98dccc2e7ea2e4f57b72e SHA256: 4cb506c34988ab325867bf4e2020baacba6ec2000875fa991045e01e29f15ebe SHA512: 0ddfcf14feaf7df77096772502371764e120aaa9ae589cc86b6f8cbac9e762248277b932dec4eb4c21e5bd5006928bda201ab18f6fe5ff678c3ffccdebdd8304 Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1475 Depends: libzenohpico (=1.3.1) Filename: ./1.3.1/libzenohpico-dev_1.3.1_i386.deb Size: 327464 MD5sum: 701ed5c8c3d7a525c82743294974999a SHA1: 78ba4dbeb4acedc676960706918b19008a7c6c27 SHA256: e02de32b9a137ef3fac38eb164c5474ba789d1bde03eae79c9563475834b9df5 SHA512: 9b5848ab596c3c3a921b6d9b2ea593a85bfa026a6d623831e1a80fc346fbf27e3665e0218bf89fe6eeeeb7fe5836cdf8388c54df6fc2fcc04951a61043076181 Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1399 Depends: libzenohpico (=1.3.1) Filename: ./1.3.1/libzenohpico-dev_1.3.1_mips.deb Size: 284818 MD5sum: 35b7b392b0e67076e7012217d3867085 SHA1: 71c8c53b350bbd1b583bb66bbf0fd3d260c4857e SHA256: 34dbc54becb82eb9f983c0c5792cf58f2c52ef289b4f1331d418dc8573d3b89c SHA512: 2694be90e8fc964238d24f50d9717b610ee3c400e5c25ac4a8fbb6f4a82e5aa014a621a0749f66436517650c71afbf187dcc478da2c03b4d0bf45966181807da Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 496 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohpico_1.3.1_amd64.deb Size: 183774 MD5sum: dd63e79e78e09e7a134de1d240668952 SHA1: ccf1c337b4f515ac16acab03d188e640803664f8 SHA256: ef58a02f9e664428bef579c596b26bc42391aecac988d1ab011cc7ad84f9cec3 SHA512: ed17dc118d204f8b5f524dae109c54990d92903e3e0b6dd80e73fc6e00c4c2b2c972280f054c8d1db68530459f0eee9362eb50bc89990a1f0b6f1d93a3e266c7 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 391 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohpico_1.3.1_arm.deb Size: 158250 MD5sum: d146291364c941b227e7b39298cf9338 SHA1: 154bc2fd5edf90a33f8aa98af7bb72341c483ca9 SHA256: 8341f5fa3e0fd5716691eefc5adbcfc77c6025e5a7dff63aa338c1b40c3c285d SHA512: 2e1c41ff640036b6dd62c8fca5cd18dc7e117d79182c7f3dec3c8debfbc7eabdfff32a20f1a39637a2a236f5ffe533d52d714eae8ce3722e88b267dab30bbbe3 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 506 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohpico_1.3.1_arm64.deb Size: 179876 MD5sum: f951b86f5e7e677c9ddea5cf3893f40c SHA1: 6fe2c64a2a5bdcaa4257ca35ba530973e1649d04 SHA256: d7f7efa70bdd27de541f4f77c0f40d9d4660136650f3349fafe85a7c68faac50 SHA512: adb4b5133a3250992ca4e1555ed88f2d002e08261536c44a41b87bebc0f0d4abed1b09efc06049e116198271c9ff5cd45ebef2813ced35b2eb1a5801663ca6d8 Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 366 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohpico_1.3.1_armhf.deb Size: 150416 MD5sum: ed3c9dfcb668f9e2bf4122dc8e794b5f SHA1: f95a555d73c2abdc412ebd18d44cff00e19d5480 SHA256: a12ffaf32d35eafd6daf64dc2257b10b6ac1f065e406900fd662e139c7aa2210 SHA512: 3d6861e16b836e1e8f4a91eb448ec3655e36cb073ceeef6867876ea2e949933c4a0a9d77c03c27c8d476825abd4c7bdfc25bbbdc33c158893fe683ca6e544bb9 Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 522 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohpico_1.3.1_i386.deb Size: 209746 MD5sum: d270aac59c18ae251a4d0979afd967cb SHA1: a15c84cc682d1f33a293024d1bace8cfce36076b SHA256: 242941c5d2624c243c5d460ffe127623bdc23d48b2ffaf12c68e622c8831bf7a SHA512: 1d170bec9e8e1068bbe6526bd61d494fcba71b63af4b02ced47acb76866e978fa512fd5134964ba5a9162b600d827335015e8fba72ff8785a4a4e465318f7b3a Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.3.1 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 476 Depends: libc6 (>=2.12) Filename: ./1.3.1/libzenohpico_1.3.1_mips.deb Size: 164722 MD5sum: 934b4c1f475ce83afd0eb83d447bb2a1 SHA1: 3258d4a0c5cab9e42cebe4d18102bd0b57bb10ba SHA256: 90cdf600cf45c36bf03622cc1e74258809aa1a4b7c000a16d711a713eedd7d6e SHA512: 5eb852b95ce440c333cbefbec4d5cc2bc1d8ff60cf8042d21450b9f5045d6e357db897cf70076e8eb5df7e34e954a241456cab312f4433ae7d509e7c54d98799 Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15521 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-filesystem_1.3.1_amd64.deb Size: 3987464 MD5sum: 463c70f26cb7626511a01908ff2d78b6 SHA1: fafff85370ab9184fe30d00551df0a24da2e2490 SHA256: 09472b5bc440c3464601012ab6d02ec9055735116f497a775e418711f05f02b7 SHA512: f5c5405ae5e75d9b9be0c5cddd235d2c4a22e584f615a1b76061c0ba730e5c28bb62a560e22fea1ac56ccd0651f14b2e9b45328e077f2a2c9a1ea16d3bb62d5c 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14104 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-filesystem_1.3.1_arm64.deb Size: 3440392 MD5sum: 29f513731b11ae1b454bf6f28b46d2d2 SHA1: 1899bb38a0d1c1c811cbe838591fdca94c3994f7 SHA256: e911fe7f6526b299100d206d738cb7ef979f8d00edb6bebf557bcd4f7bf73448 SHA512: 9800b42b42b752243506bca74e93b3e22faa0803f66471dc726046709897d6be9037ea4f385c6d703ac9df1ae1551389e1e90036b27aabe7f6d1fbba3f92dead 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13280 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-filesystem_1.3.1_armel.deb Size: 3390060 MD5sum: b9a05e4c242dd092fe195c779b5d5c3b SHA1: 065bb858d546e990d14e62a6cd40a4636cc1ae07 SHA256: 5bc9144815a6a7edaa6595fb9b6d713d9bc21345f07f9565c712296237b08525 SHA512: 8b0b1fc75d84fac5cbe0f3ab3e248908908a5fd665a0df7b18eec33212dc1f80cdc58368637a436b3accb05428980f8f2a1fc663a50975987607b0a18f437ac1 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11241 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-filesystem_1.3.1_armhf.deb Size: 3500724 MD5sum: 1a2e4f7ca6643bb88a4f936e88478e3d SHA1: 8e53be08fddfce756954e3e38ab055592866da4c SHA256: 16b1a70634582ecd34b2094fe8a90d877a68b899afd31da1c77c513288d05d7d SHA512: 91316975ea07b4ad4306127ec435d2bf42eb94d45f65eeae7bf7e1495c156e491247971b3004c4c1d54ee5ccf8eecfe4886f078cc520a0cbe2be422ad8b691b0 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8057 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-influxdb-v1_1.3.1_amd64.deb Size: 2077092 MD5sum: f8872f6c2f511af880a7d8e42ffce799 SHA1: 9ed20cc20b1eae486cef845a5266929918495ed2 SHA256: 44942d6012e223817f3abbd407333b4fd5584c41e38e0d286bff8cc819be0266 SHA512: 1a5850f2d24ef049fa31326f4d25011ee001f05c8e43fe6a3414653527c53f60475575fc083565d1e46eb8eeb3eb95572ab68cc603e3cb0b15d09e0164d344f6 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8013 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-influxdb-v1_1.3.1_arm64.deb Size: 1897768 MD5sum: c86955c499a40b1cc1ddd9927c3a2cc4 SHA1: 7ac3a1203f28ad84db53f51795a0eabeefa9c1bb SHA256: 9b252a167489eb50a166db8b79b35a11dbbd47863a954cfa00f27920a33bca2b SHA512: 6c079b39406d89917107252d8b3af9f328a01dbc5f7231bb30c7e1b6a9fdbb573aee99a73b65b48c26a6e8afbaa945aabc5b0c28efa1886587d40b3514b548c1 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7120 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-influxdb-v1_1.3.1_armel.deb Size: 1728340 MD5sum: 72bf341897b7c8218d4406bd1be2db6d SHA1: d49100e1d471fb0737553be25c3c11f66eb88c68 SHA256: 2c2d9f981400d9c689443b5a1267925ea990eec06fd20b7a87fb55f908010e86 SHA512: 75ba1bf25b76c5e0fc24bae3e383a16167a1dffcec2d3556cc4f29789844abf2304883340a6184f5465f4f28a637a5fd72e5c52e7e6133e0b21e90af1cf13a83 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7017 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-influxdb-v1_1.3.1_armhf.deb Size: 1723256 MD5sum: 398916defa60145a6e3143ffc1c14595 SHA1: 2c904caabaa0c707673926554eb285e6846b8c9f SHA256: ee0026cae9986493edb3249c8298735317ba3a18bc8a4045d6d6ee5ecd4fe985 SHA512: e925b160be271c5490f4bc82d89d87bff5f8626d16cff69248a42c5aea0b27773d8e5ee66a11de33d09e3a4a35438fb2bf33b9acbea3bd2bc1bafaff5574f615 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10767 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-influxdb-v2_1.3.1_amd64.deb Size: 2792620 MD5sum: 1c8855211325fe7d6f2e32ebd2bcd6e1 SHA1: 346a1b5d6d94781f82bd3033f94bf8d7ab3b2d61 SHA256: 9c20ea149abe1e7eff4af4d16d9ed8fd84f791d9b979f2056c7eedb0010c55f7 SHA512: 26e4b8b2713230650f254fed1c31730a4e2db7f8804d977db859e202dfc5b6e0ba5bd77b019dcbf05fe31b53ad700f55e693ba9e7f39918432aad19c6d70bc73 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10729 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-influxdb-v2_1.3.1_arm64.deb Size: 2596952 MD5sum: 5af28b9df5cd0d5b3dc9f40dd2d0bf14 SHA1: 7c991b9ea50eac214cdd01a816f4003f9bec67bc SHA256: 65b606a82b7f4edcf0f31949b78a7be20765206f396aeaf53e02cf45a19d7bd2 SHA512: 8ee7b4a7d3c7f31bda82be5b211e74f2113df1fdb798adb2d79fb1e1481ec9e22c7b5af944f3f98c42fb6f7715196185fd86347486787ffb6f08824658d8c2a2 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9666 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-influxdb-v2_1.3.1_armel.deb Size: 2397268 MD5sum: 30cbf4e7d0def9468026bbae92ac9255 SHA1: 4d205da4c5c40f2bd29a0784cfe4bb4d84bd2eaf SHA256: a4bd0428a63994cf0e784356ac1a484836e85df09665960209c940e101b842ff SHA512: 18d80f21164a87b33af20dfbb4ef2fdcacd1241ce779b7e8dd9fcc6f881a69aca140e0ebe48c99424693c3a32446a4fa5554fb83560c524f2bc21b8ec21b51f4 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9523 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-influxdb-v2_1.3.1_armhf.deb Size: 2415404 MD5sum: 0504b498e538bca0fc0d1d731c9d66db SHA1: a97a445780cf754be48f0f2f7a5b76a9ccc5fdbd SHA256: 86e2a657db39048509cea4193ee505eef61aa5b8014a5127252bcdf04a9eda51 SHA512: fbcd98ac9d8dcc89ca3d558681b0e0a57c82d163019b0fbc91f0735626821bec09a0698ef819369cd089372e4c7ee4d979e86ebe949d6ab050f96b7177739653 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14472 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-rocksdb_1.3.1_amd64.deb Size: 3766616 MD5sum: f3a2deef7d35ad17e76ebdb51350fc41 SHA1: 33d95414d9ea85b04f86f849e538822f8ab97276 SHA256: a88adad10c1c12a377666059eeff54bbe83e1265149e03cad694802cf3567e45 SHA512: a2de535935719b1055163c9480507d30227ad141b4e0d9ba89c5563cfc10939c437df96050b0675d2597fb5e813b7169fb9083f36f3453dd1d237460f15d6703 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13025 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-rocksdb_1.3.1_arm64.deb Size: 3247628 MD5sum: 71c2c814dbdbe19f86939c2e4c52b98d SHA1: 3ead018453f60e43d7f962a0489ffeead17b33f9 SHA256: d0c99355933077a2e423b699f0e57ad5a28cf49873cee92f3a7bc577e74c8585 SHA512: c92da574b799ec0fb7a865e91d24d07c18bef3aad5d04f448b00320a2c3c5ed549fc5b62e46a2292f22e3481e0d188ba8e0357beeaa1637617c2c85e2dbf7e38 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12432 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-rocksdb_1.3.1_armel.deb Size: 3222384 MD5sum: 020124a69786a8d764884606c90a59e9 SHA1: 8383d4692625850ff54170502936f2e88ca4948c SHA256: c40d910eca6614a069ded463a8512bd29154b557459e2be96560a071e294cfae SHA512: d52934709582ddea1d4089f09bb9153dfb51d97cf4123a1e47f74fa6a1641d38c7f24b11f424fc2b04990a36186067dba7c4bd80ca28875ac475f87977092db4 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10357 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-rocksdb_1.3.1_armhf.deb Size: 3338456 MD5sum: 4454a9290d80225ac9237a31a2699605 SHA1: 4c2134d1ab11476e47821143f3a8b90afc80cd1e SHA256: 4a2fcdad0fa7e27c015e29de576be82626d289d3d42ebbc336f76e771a2c28e5 SHA512: b3459ef5d65fb2be4f02a5aa0937fe777396b62a241e2311525dfcf5ef70879539b3b171b622a1ebc9986a2a5c583be02d69190b73a1175f8596cd8bb7fcd401 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20339 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-s3_1.3.1_amd64.deb Size: 4426008 MD5sum: 1741660f013bd085c46ecd10cd59ad3b SHA1: 0180ce9d6c7b0727102a6b4e5ccfe705f174d9a2 SHA256: d0b168861adb42beba140912cf5f3ce7a29eca06187be6098e1a86ceb82f600e SHA512: ab3c41c362a50cbe81808093b915bf7a68a8841a662907fe06927deed9096c5bd2f9dbbef6dc870174c0eb21cef9269bc5d6e5fe67f249a63a091a6d91f6cc5d 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20563 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-s3_1.3.1_arm64.deb Size: 4203596 MD5sum: 5e8c88d6c3ffa14628f00184e1ae89ac SHA1: e2f9ce9cf38a70989d333c0e533538c4713e07e9 SHA256: 1ad6b2ac4938231a97fdb8930ea1f062be84d068331c43753038fe7aaeaa79b6 SHA512: 5d84517a5defc1d616ba771878d2d542d77322829150963dffb79da2b6f48c7100a2f327d9104617623b47bbc80a61bb1e39bb6891bc8e2f7206a9fed0073966 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18964 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-s3_1.3.1_armel.deb Size: 3905792 MD5sum: 25a776a34c5a064fc56046e985ea84ff SHA1: a6e64c70c00f4f98d32c620ae50f8225b571a13b SHA256: 6ce140ff878b2111ed80730f6b05fd3aaf00ee6835dadf6d7f6c34a2d4b8df98 SHA512: c8555139425797d92a26eabc8d5287f65045a29568ffdb54c5d068eedeb43cc99473068f439c293422561c595767a66427231447ddf9d577675583ea42ab0423 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18713 Depends: zenoh-plugin-storage-manager (=1.3.1) Filename: ./1.3.1/zenoh-backend-s3_1.3.1_armhf.deb Size: 3944748 MD5sum: 6e4873121ea16577f45f39e213fe9bd4 SHA1: 8e82a02bc2720a3afc889eae32d6a48c6aca1107 SHA256: 168196a66723beedda0a470f20e56e97aa72433849d8b5c218364fc5a31912a4 SHA512: 0c07296edbe08a96e4725e6f23af74051a5d840203459e9e7bf7c185348caa4cc58e6c989ac240ce1cadfc6f222803bfd442985874685863ad4aba7608a6557d 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-bridge-dds Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16089 Depends: libc6 (>= 2.38) Filename: ./1.3.1/zenoh-bridge-dds_1.3.1_amd64.deb Size: 4642676 MD5sum: 605967451ce6a21c5430fa6bdde985af SHA1: 80eef0ddb54b301240703435f147ef0ceb77a5f8 SHA256: 091714cfbfcedda9bf1e0be28c84ccfba19109207e43f90d2ced9e6d18b6a349 SHA512: 54acc4d5a4ba96e2105423d9f03725718559a940e50de2e345548708c3a82b0f1f3777755dc624f103b5c01092df17438ce0d4910068db4f015d4e46b2454032 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14845 Depends: Filename: ./1.3.1/zenoh-bridge-dds_1.3.1_arm64.deb Size: 4147196 MD5sum: 3880a93dfbe12722962968ea5dd6e6e9 SHA1: 1b24cece1af4ea152a00b4d82dcc84fa00f33166 SHA256: e6e8a8199ad0d7ece186cd82d8fc4141b73fd2d2ae13c46b05b50588f4bd2772 SHA512: 817d8913da50a3c326f6f5c6a80d3da6b4a8ce16b32b37aec616d88703d6ac133bcd95a5100f9a8257d6e8ef39945172ce60d69b0caf880831f49665b12af09b Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15230 Depends: Filename: ./1.3.1/zenoh-bridge-dds_1.3.1_armel.deb Size: 4237556 MD5sum: 56f49c1bb4290cd9e5acc638379f3df1 SHA1: d0841ba64e469cf3b197e60e43d6c23cbb037729 SHA256: bef46226c8615805d5227834a54f52b3a246da6a543d934c13ec397b7e1ac353 SHA512: 354d4bf7f157189ebb8e437be592476240adecf3270a3d306fb581684cd2d9a19e3c31f756fb4ccc8983eb5c710789785828bdbe3db00fd639378207d42fc41b Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14685 Depends: Filename: ./1.3.1/zenoh-bridge-dds_1.3.1_armhf.deb Size: 4264296 MD5sum: ad814da0232fa92e22a210a56446d60c SHA1: afd21d2f8ff3c668fe9ac57b9ed38696ce116b58 SHA256: a0b87e2286642bc9d8d09e4edeec2da64f45e3ccbe38a7c445fcd4c2b41a48cb SHA512: 9b3b9c78d900efbea20fc42d58a86a53e3ab1709b2e6484fbbc56faac0703dd093cf4693dcf6e3772ddf3f545e92e5099e24a33a37d79d3446516281ee180d16 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-mqtt Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16025 Depends: libc6 (>= 2.34) Filename: ./1.3.1/zenoh-bridge-mqtt_1.3.1_amd64.deb Size: 4331324 MD5sum: 8e95efeead6e773fdedb05750a1c76c5 SHA1: b89a787968596b1a7cebfeb5fbefaa16c420ee80 SHA256: faf22586b9b4b579ff69584c796293fbb7a9746a3c857efa3ebae156d08c45d4 SHA512: 4125da2231863258d7ee3a5385a639c0d08d13736b709f8dbfedf75e7525b5bbdbb7a61cc2d999e93dfde9222b9cf19b69027d935fd580eff29868b40058251d Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14743 Depends: Filename: ./1.3.1/zenoh-bridge-mqtt_1.3.1_arm64.deb Size: 3854944 MD5sum: f0f7d0c4f72500979cc4bb3d067ca0da SHA1: 6b60999b53bfc72264398850fd08ac9b793e78b9 SHA256: 8ab2b1adab4e6be86477969640244ad38b14e9e51e21d0610394e4cc57a5fd29 SHA512: 20801ab557019136ac7212d27289e2734af7a38272a46284306aa31fd0f0144d3fddb551f191355e0844a2ab25555830bd655ecefdd18c3ff71fa12b35370aa6 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15324 Depends: Filename: ./1.3.1/zenoh-bridge-mqtt_1.3.1_armel.deb Size: 3972104 MD5sum: fd91746564b245029f8328465e495874 SHA1: 6293b52edf2effe66e3c68cdf4bc59dd824b251b SHA256: 8ed9e2a09a54c3e68fdc5135f2a44c1de1623ab51b7e196768d1ba086e8844ba SHA512: b87c058dff6832cd919ff7e9cc398d183a1e74f65294a63e0e7f7df2ec26bedcdb5a4d688070ee99e04aa336ca798bcfcf9c270b8cf9f6257efd52e5e0f8f433 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15001 Depends: Filename: ./1.3.1/zenoh-bridge-mqtt_1.3.1_armhf.deb Size: 3961424 MD5sum: a57cf007714c27e52588f667ae91b7c9 SHA1: 84ec80e76324a7541292ca39dcf8f6e1c0f5e6e6 SHA256: d56cf83777fafb04ea7913c23d232efa45b942119efe58195dd8befaf7561215 SHA512: f498b055d8a5facb6c608d9e67f766a63bbf0723a65872f5c756865ec76eaffacd159280eef66bdb6417dc3ecc5b0b0a0b34f8b2fb80e51b45fc817b0d9f7e72 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16718 Depends: libc6 (>= 2.34) Filename: ./1.3.1/zenoh-bridge-ros2dds_1.3.1_amd64.deb Size: 4763964 MD5sum: 4b339298381134c788066372d63686c6 SHA1: 60a9ab0e49b3afbc48829b1715c3e2f340dad7f5 SHA256: 26bb432b3b7a376689ecb075d672ad26f2cc11f3f9182009a16a76f022eef0fd SHA512: 0c9756b2a7b0ea4fceff18e232251e3d7f37e0b92cd39356d610cefd5e4640c5bfd0e977cf386d136822cb01123b07a0e32433986228eae463325371bd6a5a63 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15415 Depends: Filename: ./1.3.1/zenoh-bridge-ros2dds_1.3.1_arm64.deb Size: 4260292 MD5sum: ea3421a885dedad91f498c6c83ed02f9 SHA1: 4c4015327f13b7b97aa6176aca1199e70325a0b5 SHA256: d391a0ee854293639a7519959d732cf4f3685e47ac69e0922a5809bb9cb8761f SHA512: c87c3301497992fb9ec6ecd09d0d9cc9252ab77af3d16e8659db424bef5c936026322be9415b8cffd7b6e27530f4f2bba6f4295367d2d2ac83df13650cf890db Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15772 Depends: Filename: ./1.3.1/zenoh-bridge-ros2dds_1.3.1_armel.deb Size: 4358892 MD5sum: bde583c5e96c9adf45155801a6e2a7fb SHA1: 6bd0cf1a554b62e5161911bf730b7f495a21f3a8 SHA256: 12960d7a0a49a42cd0448c2b49a30ccec90a343489aa0f8777515534c60f8410 SHA512: 271cf3255a17d946338d33592418aa9550200ad464e4adf96205479ee14afe6039f1f845de9e24ed1251f8ae2ec858becdb85461478beb1440d5d9e73fe89bfa Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15230 Depends: Filename: ./1.3.1/zenoh-bridge-ros2dds_1.3.1_armhf.deb Size: 4375252 MD5sum: 36e5f9121d0c11c1d1f5b0a4c60ebcdc SHA1: b5e12e1be2e4a1c6cc212ab8e9d359cb4caac467 SHA256: 82480a086aa9701ef36bc6595416d028f360c8375e4e04fb6e2c2d408144e80e SHA512: b4ef0fc6439dc2662598e3795a837dc9155dd793a27e6c33e287284cd57dd14f17844c7211b614db6cb6c4e1d158b06a128da0f21f72cc9f609a7b212eda9073 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-plugin-dds Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6329 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-dds_1.3.1_amd64.deb Size: 1708560 MD5sum: 78a96a29d443a41b37f87400162b20ea SHA1: c43a39d42e36b60ab0567662ab750d8d85e0df76 SHA256: ba2ed84fb0f33d0d64b908bdf831933ca8c7bc7c1f2442e2056c7325dc8cbc3a SHA512: d76852db574098a7ce4ebdde231e5db605d965067e077ed29313a6fd9289d274d20c7678954faec9c64bcfb2f32983802c5307e76564186bdd67baf5991cfda4 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6262 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-dds_1.3.1_arm64.deb Size: 1559044 MD5sum: 4b261f6d8453011a0c0f1989b703bee6 SHA1: 4e461551bc91c877b8be72c3285fd7916c46128c SHA256: 3a6f41c75292a0addefa7e9f902d4c75e41def566a7d04056cc722bdf08ebd48 SHA512: 03e965abdb60e696f79066ea43d75c3f0af1f44181dd7e3b12b63c33d21a5637911ea1dff3ab5759cf5bd9270d923360bd48b19a0cd507ba15bc7d46ad84dd31 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5830 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-dds_1.3.1_armel.deb Size: 1563660 MD5sum: c4d95e607c2941826e2e74f80739c043 SHA1: 1080c1c5c656766337b5d14958b06d13cbe8875d SHA256: c39a3fe5b981fcaa38b7600daa2679d3c83cf86211faa4bcbe2ba63cc7e05774 SHA512: d6ad41a2017c04b9b6ba95ebf35b2a27afb9e35954eb5322e57d21f13b5b7905bf574e592d0addeb502438fa4e714e18274270886759d56e69543c7454381b31 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5484 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-dds_1.3.1_armhf.deb Size: 1579412 MD5sum: fa3e04c9a4231ddfb26c7d7ad0492493 SHA1: 22e853752a781d5fbd66456cc785eeb462ce548d SHA256: 5762a61251510772b3568d955b5679d1492958f6733703cda792f0e47ae8b74e SHA512: d6ed378c55e4f2046ca51ca641fffe3d4f023d30c8cb8dd338cddf3b15ec8a72682cc1a2d20536add5871a268a84d7908fa74df7917649ed7eb039dc6cb15a97 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-mqtt Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7681 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-mqtt_1.3.1_amd64.deb Size: 1922816 MD5sum: f59d4a7a6b93d0dbe76053c296a25a8c SHA1: ac1689710d0e13914e0e39cf4d1c0658ffd6d5a9 SHA256: 470760d59597091c0acd39c15e2423beb1ff14b305cf02d5e0490a573fb4f407 SHA512: b8916454c4b3d9441e7c23d7de1c1f2f83febb5f07de0efb0c4e3058470bf25337d45d8d3d012c32272853b9fe8a2d8474ff950108aa95cb58c77d10759768c7 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7427 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-mqtt_1.3.1_arm64.deb Size: 1749628 MD5sum: 6aee324e8d97f0cb55f708089188532f SHA1: d4efc24023f91bcd285cf1b5650dda242e12db6b SHA256: 0821e004a19f2a61a7cebb617bd238c6cb2bca2c3e4c43d5ff6342063d1b0f1a SHA512: 5dc8e776e3ed37e8c68082a485dfc1f9e9901ac8d3c9567b95465def3934d10db868edc7d04f14990f55d8afbca2715044d4ffc5757b773e93f530a252f3bfb9 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7062 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-mqtt_1.3.1_armel.deb Size: 1633816 MD5sum: edb1c557bbec8b0a8d37ff70adbc8f0a SHA1: 55ff2901a73792b61088518e27838175d3b2c8ba SHA256: c1b189d5bfd7505daeb169c2529f9306ef5c894811249c2dc07d85ccef92a449 SHA512: 4507117f0aa16ae4129736eb4f1095aefd27514778881c82d0a969da585bf417e103087d6ba62bf16200a899b0054dce02869e21bbdd646f5cb53fb38692d268 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6880 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-mqtt_1.3.1_armhf.deb Size: 1639984 MD5sum: 6989ad98e2f93b1dd8932fcefe03bc40 SHA1: ec3e6d7dbe6afc48ec02537e46824680750e2a51 SHA256: 17648faa1144bd2800f4c12a3150359dd33c3c76edc689506949f17886e9c13e SHA512: e81fe5fdcc35a4bbd956eefebc44ba15d93e5a1898a5b3c85142e97946432b9c55d9b10b03871b34c1b3f4da87f25a9c2480166e69bcddba4962eb0d0f2a743b 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: . ```raw 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/](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](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. Package: zenoh-plugin-remote-api Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9793 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-remote-api_1.3.1_amd64.deb Size: 2469348 MD5sum: 7f0fe35a1985f8b2a50feda0d1f2b189 SHA1: a9328a5347095ceaa3b003c5192e38b207c10657 SHA256: cb847e24fd04e29493e5b7e3ac5a03589946d642935bda8a8e6149669f0cbd5c SHA512: 4cc1976380404ef86a39d86d88065bcd1306d48ccc35d5fe2274fd478b6ac4ade39ada65b2b3344048b584df416af3dfc920a9c0d7c3ae8cb705d6415cf952d3 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9798 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-remote-api_1.3.1_arm64.deb Size: 2290044 MD5sum: 9aaadbc416767a3f727f5f433f6abf26 SHA1: 7e06ac77954119c4b813318b36fd926ce96a1e21 SHA256: f2286cdc219d617d3d476ab112511b4f877072130e9f280ba5813c28defa863e SHA512: 1ebbdd39254f87038c022554b9a8ccb7ad3684fb884a158e3fe6f8a7f2a5df7296b41c465274cdddb75b71d59f74329f300524535a7277f1a0c45dc50389ef2b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8806 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-remote-api_1.3.1_armel.deb Size: 2062596 MD5sum: c901d3f0bde04c721994a5f78f5d6848 SHA1: 842be981fec84b7714651a49adbd35b316cd594b SHA256: 9565eab5626d43611eae7a904f38934da39c62d0a08ea80f31c5ee4771fe568e SHA512: e7ac2fe8e7d59e09bec4f3cef30e152bdd09e3d1c78bdf9a2f8faa61594cf947e870ffd1735f002dd123c22bb77d9655f7c50c041e3aeeef1c26e50d5fd5515d Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8635 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-remote-api_1.3.1_armhf.deb Size: 2069112 MD5sum: c20abb443252a75aab149d9bd53a8817 SHA1: 275400d4ef72447c89f4a599e1bf63b585b6cd5a SHA256: 37b4219bcb7c88233e0468dad75a006e64597f6a05ab7195e151f8e09f6fdfa1 SHA512: dfa834a7e103a2b21361c223cdbfb15b0897408c717bba011879ba71e3d82838de1564a75deeb16d4053304a5a4b70ed7fba79b290bed225d52c87aeb6a48611 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-rest Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4614 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-rest_1.3.1_amd64.deb Size: 1241800 MD5sum: 36fb8c94b4dbdd760cfb0d58aaf40ecb SHA1: b22216909d5d9289e00dda761f40e0cfe015931b SHA256: 10d63be8ba11087b3bc71111487e11e9432634113e1154f74190885ec0664ad7 SHA512: 427c24175cfc5666cc426e523ba4656204dcc98b0657da8c7ee4e27a96a894803636d720494594c0825d6b6f702a0b21fdf926b685e945e15f1f80b93d9a0d5e Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4649 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-rest_1.3.1_arm64.deb Size: 1149140 MD5sum: f607e8203d646305fe722bc007d17d0e SHA1: 59554eb8e5d0eb209ba46db2b58210cc74c1b60a SHA256: b68142c5c826dcb6ebf214237d6c70cdb921d6dcba2d1ebd65e8b6bd27e85df9 SHA512: ae0509a1a9e2c054e10f373635360809da46ccfb8fd5a9d6c6a3b283e0c77852833d5d6300945d1fb99f9e84eb22cc26ba512b4d5079807200cb91fdeea2e074 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4384 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-rest_1.3.1_armel.deb Size: 1184640 MD5sum: c773d1360dbf7da1b7497718259116e5 SHA1: d56325d1632ac7bc4eb9ccaaeae7054403e5aa86 SHA256: 7782903feac36e5e35b212514f3e630b1e580e8296069f21ff5c8a1614d308fc SHA512: 927aba30a02acfcc1c0defce263ddd8d2935472ab0641d25b396e370c7d12cc8bab8c73c7fdab4c2a1af9d80e5c0912d56ad091b22616bb7122c2196bf4577aa Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4311 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-rest_1.3.1_armhf.deb Size: 1180104 MD5sum: 7cf04ad3568efef1597935e27e3f4119 SHA1: 0401b3b86c6bb742049c85c227e7df90d2752596 SHA256: 54884146b06dca7e7e6272fbe4e7ae2ea5bd3a6f8f3bbfd9e1aaa2344c447e71 SHA512: 9305e23cc67006a32dc99999e0c926ec39c981d07c13a0ddf355578a1cd4c52408612a181c2d884607dcfd28aaf191e837260c0d27e245af460294547a0e56c0 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6892 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-ros2dds_1.3.1_amd64.deb Size: 1813908 MD5sum: 7349e6cfb887ed58000823e4dae59409 SHA1: a4363ded2af0455a1b67d91b000441a69bc92e01 SHA256: 83ca8f683f527eb786a161ebe3d66613a39095eb12ca4daa8dc66ae09b7f0671 SHA512: 4ea7571ffd38194823b3cfedea5a50ed9e3dcc9668f6d066e86f6b439b2e5eba6bdf19ccfada0787cb3149c15d1ea25824891b2fc85745d135420a4ef7c6b1fc 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6784 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-ros2dds_1.3.1_arm64.deb Size: 1653624 MD5sum: 80ef2ec74e67abfb91c3033761dfc7b7 SHA1: fef056b06f0eeb8436c1916322e1f0947af62d1d SHA256: db804c80474c0d44d4c9e744baa9a646f3e7f264196a9cd76f7091bea98217dd SHA512: c4df2f08c004e735af61eab16febdc7a18674df41dfbe4db801b5cce762ea0be9bf5b523962acc96a58ba4ff71e0c79a5a7163c60a225e3d319c4bb940f7c8b9 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6337 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-ros2dds_1.3.1_armel.deb Size: 1670256 MD5sum: ec3ff28a5b252737b700b3e4b2ae3790 SHA1: e2ecd2fba782d3e4140fa87d5542af1251c6a117 SHA256: 0e4f204e5e3a6b169a506e149bb930b7c1612d0c7f9b15f9bfb53a4d8620b102 SHA512: 09fb12b2b0337d2b470b374f2826c0a0669bc2cd8d391ee9882891d9a4f329582e79dc9c5c2edba4f300d40db69fa09f67a0d9170e326876807706b5a9cc5e9c 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6002 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-ros2dds_1.3.1_armhf.deb Size: 1689964 MD5sum: 9eac71156864db3391fbe9c520ad38bc SHA1: aa98888d705aa124d5b8d471fe198124b5fdcd37 SHA256: 421a044971f8e1f3298f3fc8f68c91a21c3f5a5c95a774a5e9ab53c60e8a333d SHA512: 1a38cf18b71bf5729828e19efe4364adbfb63fd43d612bdec9bbf5229cca70c589c0dd194e9227f7f2809cef6c7ed67e25abc43db54c46677bee99dbad263666 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4353 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-storage-manager_1.3.1_amd64.deb Size: 1135428 MD5sum: 30390ce605a58cd90bf0c2f69793ad8c SHA1: edb54d4fdd06d8dfa7a7fc41ad022d7a13514492 SHA256: 0df3eeffb3e568cf576efe1180eb2865becb1c40703c8e3288992ba3babb2d7d SHA512: 720d7e235fa0f5196d7d935eaf412bb2cc79d78f95b9d08ea92c70af4583fe13d780a53f5a4fa3cb16a7a628cffa969b3ea222ad98d88f1c5487aae960427ae3 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4374 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-storage-manager_1.3.1_arm64.deb Size: 1050608 MD5sum: 573107859b155904760878bf39048edd SHA1: abba961f423f644aff26a0577ee2d8c9b3fcf46b SHA256: 2cfcaba540cf99ff984cb0591b3f9c5acb3fa530c8731530718d6aa00b73e4d1 SHA512: ede1421e102954123de636e80a76ae1145b55a8505efb40d8ba92fe0d50cff990631bf9562c1b6d69233d551925379ec1714555939e7fa5da8f3b0dc81addd6f Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4129 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-storage-manager_1.3.1_armel.deb Size: 1099620 MD5sum: 653853e7e243fa0f3b36122c3c963e21 SHA1: 15fe612faa6214f4cff41225c6cf24c976efff53 SHA256: 9348d7c179707625c61aba71762e0d03248f47d3032142abc261067d0cf3f21a SHA512: 96f4a75a5908eef0135ac00b8f8a58ae4a2d9296cb3dd06cfd02514b329de75dea5dfe0eea6c0be46098c538dc62f253d166e70764d1367ccaca3c0398b6fc1f Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4041 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-storage-manager_1.3.1_armhf.deb Size: 1093716 MD5sum: b3215e3aca4036c2c0ba88bf081ea136 SHA1: 645cfc1aa6d0cfecb402391c912ef70d87185bc7 SHA256: 894f86bc98e3df206ab56d8454856ea151c9ad72ce45afdf0f2245397678510a SHA512: ae8eedde49ccc2f80ac61da40bc2aeb8bfdf2006334011b841dd453c2f0580145380be158d2be4b3a36d8a08f7cd67354c19d9ea8bc53de73888f5b6d3052460 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-webserver Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6958 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-webserver_1.3.1_amd64.deb Size: 1655408 MD5sum: eb92ceba5b465dcf6f87ee2aa42a45a7 SHA1: 3d9eb150ae903b874cb1c92e9802554af38b7306 SHA256: 414bad9faa7cfa1140540247f112e9dbae6e09ec63e18a3c73904d38beb9cce3 SHA512: e9180147e7e26f21dc322c72a274c9dcc7e71965130a352cb9c28e7f518fa7e25927ddce5b8332c57b49a2e29e65c2e9c9fd532ca0a32e5625bb382e329519f6 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7166 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-webserver_1.3.1_arm64.deb Size: 1552180 MD5sum: 0aa5ec2419f4a4e7a742d7b7f32c36c1 SHA1: 8c26807b20db473d9b45edab59489bfb3ead6e26 SHA256: 47be48721aeaa676b0c4dba2d8596106d3ad07045d75df900026e5d87923754e SHA512: e1fa94717205dfaf6524d2f15360a87a1850242f85e10b57434ba4b9f03b74d5aedc595bfb290f651d5713f5f241f30e3652bd466b88e86de234d280b2e3641d 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6482 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-webserver_1.3.1_armel.deb Size: 1524264 MD5sum: 7055ee59f471105b3124ff7ee251dcf8 SHA1: eac33eaea3d1f35a4217a9ded8d893f8e24b9e9a SHA256: 717a6c459133117e61d065e0566a7b5cb881cd82d312f681ae4921f9ff6af951 SHA512: 8aa441c4a49231b9ec92004285465c5570f3d91d96d07219207ea76d48241740f28c10edd851c1579fe2ffe6f1c654029ad3824f45ab97951d2e0c865730af7d 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6381 Depends: zenohd (=1.3.1) Filename: ./1.3.1/zenoh-plugin-webserver_1.3.1_armhf.deb Size: 1516824 MD5sum: 482dc671e9f299459b5e9fcc071dbd9e SHA1: 726291e43f214167b6797e391679ca90c75b9b8b SHA256: 3269abf0cbbf63473c8ff54304389c29b6c7ad84da1430988d563e7c0c37e9ba SHA512: f6e7e0e2d65138a28b750b4ba2e239725c1321764af26229b10760b92443308a34b676205010ac8cf66dc77af3a16224ce797090943fc38c453b39fcd990eb15 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.1), zenoh-plugin-storage-manager (=1.3.1), zenohd (=1.3.1) Filename: ./1.3.1/zenoh_1.3.1_amd64.deb Size: 17560 MD5sum: a16e7ee624af50f4490c67abe90178ce SHA1: 381afd611d9afc6e90c498db6f1ae87f339781c9 SHA256: 48feed27360e40ca3229a4eac7211b55d4588a6a73b95aa28eb30c78b05d77ed SHA512: 19272ca1b6771b9ea494d90f22626bb279a7f33a22abfe3e9b24d962313d7f404cd8c45ef239361c3c32faea23e666dd80e162afb7a2dfd21f83de46c29b35da Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.1), zenoh-plugin-storage-manager (=1.3.1), zenohd (=1.3.1) Filename: ./1.3.1/zenoh_1.3.1_arm64.deb Size: 17560 MD5sum: 86c47d8397d7bc54781cc949815272f9 SHA1: d1773580b66d49dbb73981cd3787dc0bdb097ebc SHA256: 970b33f0ee7dd1b2cc94ecc232a604ca973ca3df35dc7a8743185ee1c4fc63f8 SHA512: 6cdd32951d4a21dec52ecabe79e83e78076de901f1b43d66939702244250da4880c408690c9cb9e922fc3b45fac57a50fc0ec7058548bb7104927ee17aeaaa5c Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.1), zenoh-plugin-storage-manager (=1.3.1), zenohd (=1.3.1) Filename: ./1.3.1/zenoh_1.3.1_armel.deb Size: 17556 MD5sum: 0ed7fcb01dcc89d8e90d877155fa8b43 SHA1: 2b616403abf1aab11f3376ea7969abd9bb37afee SHA256: f5b732451b618d5bb4e87f30ae6a04bace39e0feb95644a8e69de5ff371b6661 SHA512: 1422a08b84d4136f54a9d6d4884d3ff1fde20470434df64ca307940b67ba938d368d2ec1c03ee11a41f89341fa21abbc4c90e8971778321b683cc7d249bc349b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.1), zenoh-plugin-storage-manager (=1.3.1), zenohd (=1.3.1) Filename: ./1.3.1/zenoh_1.3.1_armhf.deb Size: 17560 MD5sum: a6f3114ac94bf9b0f49f6df3ba3bbc32 SHA1: edcd903739892690865ba7ea90214b82200050ad SHA256: de30779ed6e724698189f677ff1eaf30453390613474d662bcaa1775d289e0e5 SHA512: 1a419f2bb34f11eac58ef6444bb336f42f3217fd7b44c49eeab16c81786fa91743fe8a06d37ffccc134c89feeb248aaf900b895cfbdad4d562d29c7baf8666d6 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: amd64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13908 Depends: libc6 (>= 2.34) Filename: ./1.3.1/zenohd_1.3.1_amd64.deb Size: 3846292 MD5sum: 5a33fa5288d433d34d3ead3a4899c8e1 SHA1: 6d8ea0c2c07311244cf322410bfd241b81f0b892 SHA256: 426803239c74f20ceee0a24ddd54b2ad0c775f35353dad51f2b902f3409750f2 SHA512: 0798d363c925bac716a5bb7ed51b264943860b7624dcabd84fd497621f4b0aae5f461f1c6f478c1f63e6b64c895d208e20cebc1df0fc49af4b8f66177818cdf5 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: arm64 Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12565 Depends: Filename: ./1.3.1/zenohd_1.3.1_arm64.deb Size: 3434992 MD5sum: 00d166a2a1b02422fef8612e4ad058fe SHA1: c228615f92c585f2d4cad2bfec533f59a55516dd SHA256: 17e90b2f51adbcccf895a05ed9b0f6c5c01f609b888df283e6f476f6e88acef7 SHA512: c9704cdd22bcc757e2abc19d23d91eac85c9690ce1e5a1fa9b9d71984e91fbdfb8f5023c99758135b0e128c7745787ee724c9881ec50e20f59a70e41dca1a9fe Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armel Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13210 Depends: Filename: ./1.3.1/zenohd_1.3.1_armel.deb Size: 3602152 MD5sum: e311e7bee33b8693aedd280391ed2c2a SHA1: 33b76531bbc52d12fdf0587d2f19b321827d1469 SHA256: faf0aa56ee0a616fe20e2e7da4555ee48e8dcd354d0e5c1595c2325fdfb8c91e SHA512: e11bb3182e14136e1e5cafa830501adc40fd4a064b7953b5f7c74d988b23d8453f32ccc8ac23ecddf188cae7a9228108e001df4786466720b5aed93a9bd643b9 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armhf Version: 1.3.1 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12935 Depends: Filename: ./1.3.1/zenohd_1.3.1_armhf.deb Size: 3614576 MD5sum: d33ff1c5b7752553b6e76b4e0730865c SHA1: fe620cf0ff72835ed1e6096ca644396ea3513ae1 SHA256: 90d49f46ebde8da3654f462034d3670f539786b47f024fcdd969842cff8d4ab5 SHA512: a01b51a38726a24f70278780d181b45bd65384143c3e9de3e64608ed267dbd5e9a69bf26e11fca00b832730819e62d3add57a1ba57742388c0c48ac39a520633 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: libzenohc-armv7-dev Architecture: armhf Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30833 Depends: libzenohc-armv7 (=1.3.2) Filename: ./1.3.2/libzenohc-armv7-dev_1.3.2_armhf.deb Size: 9550786 MD5sum: a532bb6e4730874c810a42370620eb4e SHA1: bbc5cf9d43c142fac03611c158cbd6acf031f14d SHA256: 333eebe6426a9490519bf03cc6048d100dbae102b94bf0a268e30d13722dd50a SHA512: 30efb84f927e8f1c6bba0a851c254fd596bc11d56207236914121e23bf391aacd62cd1883b8cb76ae8950707186e558dd091ffab33470b805ecc6c87ade670fd Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13542 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohc-armv7_1.3.2_armhf.deb Size: 5690092 MD5sum: 6b4ccf8b4bf342f5571c639fece6fadd SHA1: 13bf0fec02a500b9f8feacc62d7cfc9dcf7ee039 SHA256: 5130317bc2da67a2bf73e7fd8ef6ce05319919eb31abbdad827c28304d008c20 SHA512: 9bc617d9bcfec5775df0b8e4c39f99ec71a655655bde6f3f25c21893068a7a8b5919491095345b1f8960a937f6c237212aa6adbe589d6cc905d2cfbfe2a1da98 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37431 Depends: libzenohc (=1.3.2) Filename: ./1.3.2/libzenohc-dev_1.3.2_amd64.deb Size: 9161572 MD5sum: 575cb33dc1a0c84cd80c196b1fa562e3 SHA1: 94bf10e3d6d349399093d6b4e150802063b24f61 SHA256: 0217df7a93293a315f329ecf68927c38d53c730e8a41005bd027136fe6f4fa2a SHA512: 5e4c9662c4b78dadb94a406eb56311e668d8663c6b7d84b96fe5de7a9bcd910aff174801a6dd2c5c9dfe3621f2ac624a8a00974d5f2564e7ba5045f5efe0b34b Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 36781 Depends: libzenohc (=1.3.2) Filename: ./1.3.2/libzenohc-dev_1.3.2_arm64.deb Size: 8838568 MD5sum: a885139b951f9dc88345f191d7d65b0b SHA1: 0f1341e61804e59600124900cd9d4b5eb62638f6 SHA256: 88d6cfb61fbd5f41942e9bce0179c9fec998291ce97973536472754cf71fd70d SHA512: 207f150e3222e9fcbae648900a2cefd1216be276650efd1f76e17abe13c7e51728471cc40b045ca3fb5ec00b15e90bb4c45915254e9bf8401609cfab4d32b6d5 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31015 Depends: libzenohc (=1.3.2) Filename: ./1.3.2/libzenohc-dev_1.3.2_armel.deb Size: 9615058 MD5sum: 8f395ac21211ec06e878602553874529 SHA1: 57a11c2593fae77aa44485b3ee1c65b46b56ae1c SHA256: 6e90a4802bed98f673bc30c23781e02279f529c3912460d6c2734b9c23636e4f SHA512: 0f2bf6ca7d67dcf19048763dce14786116b09c981e8e49e4e20f998e6970e22d7d93e7d279e1743fe09be90b07fb1e75ae9b848b4e91ea4510214e2c452212d7 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31159 Depends: libzenohc (=1.3.2) Filename: ./1.3.2/libzenohc-dev_1.3.2_armhf.deb Size: 9737478 MD5sum: 3650403d447be60ff256563b6ed90892 SHA1: 2ce489b20ac6bd75fb67ef09e48811b4b176b7c2 SHA256: b4eb6a905b2376915e80ef41ef9cb2d26f07de281932d2b692538bea07883f43 SHA512: ad0e8f72ccabd10beeb7580762c5f5318911abb3c06433c4f1ecd66077b1e60f542bc02d7020d854a1267dc7a4dce2e737c73039a13c58a78ee5fea69826e758 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 35209 Depends: libzenohc-musl (=1.3.2) Filename: ./1.3.2/libzenohc-musl-dev_1.3.2_amd64.deb Size: 9039768 MD5sum: 58f062312c5c15d802cacc3b4a698d15 SHA1: da772f6a97a1219b8ae5829112933dd5117ff21a SHA256: 7d31bc1bccde652ff06de9079fb1f4c7e3e1343b6376e5f7bbbc2555e65fde10 SHA512: 830ba39d65daa4c4d64a71220ae9f244a5299f46619c85c767c998c72cfc5183336455e5e6cd113d0c2e75d893a991982e7cfd80d9c25203d5e6d78897249999 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 36085 Depends: libzenohc-musl (=1.3.2) Filename: ./1.3.2/libzenohc-musl-dev_1.3.2_arm64.deb Size: 8705618 MD5sum: 6f6cda88ed4aa79c4d8bfa604d231c9c SHA1: 0c734f14a684ed58d5da832be22ed87ac999595c SHA256: 7e0f72bff7bad473c3e9dc1f22dfc851d691b362408e20ac602f76948b5404c0 SHA512: 88dde74e75ec40be3bf5a332f9c4097f9c213bdb43c1874f7ac401af5d80b34f7bcbf00d7884962803df671306dd9a2ed8ef5361d06e1689d369ce1bf93efaff Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 14404 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohc-musl_1.3.2_amd64.deb Size: 5715266 MD5sum: 235943c07a59eacbb627f92fc8b88db7 SHA1: 1970f01087a2004fe5ca99499c0598766b792515 SHA256: 052aa1d1cf8b10160ba4d658bf39a84d0a7784c2dfa027fa1df64f002ab05a92 SHA512: 9c2eb05e9d7f69c331af23cfbd15a27b43258b9f96297b93e4ce8d2619a82b20c8d3c4bfd9824856de487876c2f4c5c8e0ba8550f975b7657ae421299116c586 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13433 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohc-musl_1.3.2_arm64.deb Size: 5430076 MD5sum: b24d86f2748e8b039e13d9fb020785e8 SHA1: 3aba537710ab479ef5196355135521931b3cd219 SHA256: 871be0f96a5b737f61908e4e301346fd75df40e566395dbcb3b03e0a91c668ed SHA512: 9ba94b104f47e88290953613c1491a09ef23ea5982adf5d1f98cd6d73a4e18dc2c209c8425d6c61de3102d94f2dfa9c57655921a5101e18d90f7f6a5a7f7dbb5 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 14406 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohc_1.3.2_amd64.deb Size: 5708864 MD5sum: ec304e1e284d63281cf08fed10ded4ec SHA1: edd6032259b70ef339dd2d62aa19852fddf388bd SHA256: ca9afa4effacd5ec29e4282a480623d09758a3368baeea2a7f05197de60b6e6a SHA512: 10852f52715e74612d57b95147cedf6bcf522504c0c38bd4c85516cd3b3cfa2b7b979679f472bf724045e57e9b8c8a8bc90a9b6191fb1de1fbd3494c671fccd2 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13450 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohc_1.3.2_arm64.deb Size: 5455420 MD5sum: 3de90692452b6a51680ff8bac1481012 SHA1: 2d0c325015befdefde1bdd69149f214d5de58299 SHA256: f8a846153c8f187d8037114e4695c684bd18856aab00ae4a2780c5989b1bd9ac SHA512: 96dbbc78a80b7c36b8713c585fe2fadfb07981270d2b546f18b8c2c4148abcc22645330c47f42930486ae9f4b97610087092e7722a543e8b2e6cf597643a10e8 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13789 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohc_1.3.2_armel.deb Size: 5756610 MD5sum: 2708758a796c945a6e00b1c108250b90 SHA1: 2f20c519f2062f21355adf1c0ffa7229522457db SHA256: 064dc9c1528d31f966e2cccd930f90b5cec384c59b951283493cc24e0a0d8305 SHA512: 256d21cdb16a7a9859b526d2f9d6b90cea3747b02becbe4980a73dfc1fbff42aea257e72820baab003177ff8d5ae48f6055a2f1ee19315ea418107fb6e1cfa90 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13794 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohc_1.3.2_armhf.deb Size: 5833490 MD5sum: 14013059aa0a16d6b8c0ea7766d0a41e SHA1: 56abbafec93c34edcef3a6ed7cb7171137699def SHA256: cf668f49eb947a42abbc965062c83c86e8dd1c084225340ab463aa4b511b5f9e SHA512: ff4a87a09ccac5ff3e1a7aef89efe9852e9792ad5b64814794908673f61dade7261f01baf554c0eeb2a639dec479aec74ba079a53371cd965c06115f195478de Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 448 Filename: ./1.3.2/libzenohcpp-dev_1.3.2_all.deb Size: 57448 MD5sum: 44b290e965b82db0d68d527713b46cb5 SHA1: 96b854645e5ae4acaf1777fc5f0357ef5da3abbb SHA256: 05734d66419bc9b682414a1c4fcdb0644cfdba8ccd0993c4f021a93593b2dc80 SHA512: 38323fa6ab4a9b0070098ddb595d7c265f1e1526772eae9a2f643ca33447b5618528e0fee237815eb7fd90af1eddd6e152ca75ffa53dc878abb13eb10cc922a4 Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1251 Depends: libzenohpico-armv6 (=1.3.2) Filename: ./1.3.2/libzenohpico-armv6-dev_1.3.2_arm.deb Size: 252346 MD5sum: a19e31bf23bb867297634d7df1a82d03 SHA1: d09f9b1397843ea5a61b93c0010ff9d12f53e460 SHA256: 7d51cf32a90c00b7ab8a95ff3bea9c4c13bed227847d9150580f6f02a1aad857 SHA512: 36e7ecb7c0dd5c0285ee2793569e7c09fc6659c8edd50e7979e3c2103a2527285eb5535685ca83bf9a02d89118b183a2a04423e27cea257821c8f89cb4bf6711 Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 364 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohpico-armv6_1.3.2_arm.deb Size: 150132 MD5sum: 51994f2b48b2067874a1c6ee3ed1d079 SHA1: 601cc074301d48f87bd292109d78752591b7b5f4 SHA256: 0d8ab8a2bf78d59e5cb875ec9ed7c257399d17cb4e4add3aff298122b9866e2c SHA512: 1c3a83929baddd5d3b43549398af2af56b137348ca642f464fde0d489adf46465e6e79f82cca2806a797a07bbce177da207ac6a5926b3785e2a4e0d52c8823be Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1243 Depends: libzenohpico-armv7a (=1.3.2) Filename: ./1.3.2/libzenohpico-armv7a-dev_1.3.2_armhf.deb Size: 250586 MD5sum: e5ed121cc0ad6e5047bc2f305203c78f SHA1: ed34ffff45caba3bcf5a39fccf662143d42927ac SHA256: 43682ce2a513cbfdc8eaacbf40f3c7cde8ea082d38ccc3e3589372e76aee19a4 SHA512: 339bdbeedd1f3c40a8ca74929d59ae128f4d0fb98ad4901b8589b66e59ce079f5a26ad6ed8dbd41e8f87ec621805ad19499e4381a193f03d1f9f32dcdc5f46ef Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 364 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohpico-armv7a_1.3.2_armhf.deb Size: 149342 MD5sum: ce13a14519dcf79c0fc3c76ce6468a29 SHA1: 8f1434489ee2b3dd3b214cb05367655a3586e32e SHA256: dcebb24f0c71cdc0680ee16056cefd92e4027defbd5f57c117f356a09c206ad6 SHA512: c1140cba1cc83d05ddebcf78e78ef834a3d6852323308d7c1e1331738d684d6bcc356aa33094c98598474d7ebc3e43e2e0f29788c6820ea1a5f93c534714e98c Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1505 Depends: libzenohpico (=1.3.2) Filename: ./1.3.2/libzenohpico-dev_1.3.2_amd64.deb Size: 300300 MD5sum: 22b1a13dffed612bedf5834c4b6490b1 SHA1: 36866e5866ed117795af9f7d47439b01b4117b01 SHA256: 46d4d9620cb399ac6adc3645f36f46829b2e93f8d81625ac31f104f31100ecfb SHA512: 245f5ef9fa744ae2a694aab91a304f120484516e52c5486d63cc6a939c7d8ab2cde810d7eb60081f9618a3fc77549bb0abfa53d7b1ac64812702bf7328f036c3 Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1250 Depends: libzenohpico (=1.3.2) Filename: ./1.3.2/libzenohpico-dev_1.3.2_arm.deb Size: 251826 MD5sum: e12c8713213765b10f9dfc3fc7b02f00 SHA1: 6db7c3353a27bda75d5989761fc10f3cb48a9960 SHA256: de4224330b9f506ff0247f4255239f7d3711aec9f9f165fea5491d7ab15ee22f SHA512: 6b49a7a1d43596d18cb77f6da7f1cc6ab06dc96fdee260f696a1324c31d84020a15059a8b62196751e976ecfc88396cea3b9727f0d8d761104eea280c05d00b1 Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1516 Depends: libzenohpico (=1.3.2) Filename: ./1.3.2/libzenohpico-dev_1.3.2_arm64.deb Size: 296708 MD5sum: 370f22a5dc6c0ba263cd93665afc4f0c SHA1: 59f5bf96897b85b4b1215d319764a840a9e13d9c SHA256: c3f2fb8658eca27c201701dfda6e6ccacd0c659b75b6edefb0cdbe551ebf88d5 SHA512: 8362841fc38bfff86098cd4ae653881bfbb287c5d34aac68160e59d3de8542c9b2294c65f216b57a81f0ade372be683d423876537c0f796122cffb63cf8a0854 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1244 Depends: libzenohpico (=1.3.2) Filename: ./1.3.2/libzenohpico-dev_1.3.2_armhf.deb Size: 250276 MD5sum: 40292ca644733691cae8fcd636d76777 SHA1: e294f1b3a367833687c591dc10ebf768d0c7f66e SHA256: e6b8bd2ea5ba5681be13bc075ec8aa37e692f0191c4cec820a3866260512075e SHA512: a1ab0d92cd00b5dbaf7ec9881780edb2ee543aa9ae67fcd813f21fceb07a945d3d440f29674e53ef223b8a21896c4e106f4e62250f055c9b67419926f3907890 Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1475 Depends: libzenohpico (=1.3.2) Filename: ./1.3.2/libzenohpico-dev_1.3.2_i386.deb Size: 327490 MD5sum: 0da2b2e360e7faf6f44f0cd5dd46e767 SHA1: 16e2742ef807778eeb1b586fc14b41a68bc78795 SHA256: 7c883f4044af1ee44cfeafdce9c9c4d4e36f1d1283a3f754891c4498a155aadb SHA512: 4583bab201411b2a0efb0385f98ef9010c2c8df41532479053c2b223653bc2f1a02bb47e027a94169df7eb068869074977155756e75065a297e09c7b7c7de5f1 Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1399 Depends: libzenohpico (=1.3.2) Filename: ./1.3.2/libzenohpico-dev_1.3.2_mips.deb Size: 284880 MD5sum: 7d70ef456526c4ddbbad9f2e7e318ba3 SHA1: 63c8bab7632872c507bdeb6cbe7703a6f412845c SHA256: ca869bc29185e5a8cce1719a6fecf36d9962066cb289c5ed8c048c23c0e94889 SHA512: 5628048a1c283a16fde5bf8b2a64a65606fff7fbdc402a931330e3a5c8876a5d80815e803e8889b9ce99f098777eb05ffb1739d48aac27b45a273da4f75821a7 Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 496 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohpico_1.3.2_amd64.deb Size: 183816 MD5sum: 7163c8e93f44c890077d64dc0091e9f7 SHA1: 61c50f724b74abb698d28221559129d3029ac4a6 SHA256: f89738bc224225b94984b5b2726700f163b3bf71fd6bf7b358ee0485e2a588ce SHA512: 8f4fffc07ee0530e200c82295e8efd198cf45eca3e1e57bf735cfe45bc5f66b75727b664abcc92ed94b7be7fa40135a70c58d7cf2f1d47a30754ab400805dc92 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 391 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohpico_1.3.2_arm.deb Size: 158234 MD5sum: 35bdf4355cd7f86192b31c6726d4462a SHA1: bed514f01bf73fd16d3922d9ae01778b5e11b743 SHA256: b041fbb2e135427591b54414b8d6085936a4d8d8f7f9bec38abfabbdeb25f4ce SHA512: 0e6c24804dac5c4e81dcd488f5eecd5908847029c8741adb85dd45e84c2016937d9fbe9e412a429af72b84bd99f2568288dcf8f66565c03e7deae3aa22e09447 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 506 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohpico_1.3.2_arm64.deb Size: 179872 MD5sum: 20e3d41385edab534b4efef58a1cd178 SHA1: 5265553cb48470e8f3a0924fe3a0f52a9a6a2c9a SHA256: b278c4667a54e2ce77f46e8c2eac867aed93083ae0a6fe43876856e2816dd3f5 SHA512: a5537937991c6f80c9b972c2fcf8925a9084b44bf81213f5f68322e49933436bf55ce1c45e4d03d5fc34930f47af60159378cdc64e2de34f8c3daf3534f02a80 Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 366 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohpico_1.3.2_armhf.deb Size: 150430 MD5sum: ee5a6992633320ec6987705cbe1b62db SHA1: 42f156fcbf21c9f3778d49ba82745fd7642d173e SHA256: dbe11ba35b1aaf60bec0fea94f37b16fd22a7a52be4daf09850a0c7348cd3b36 SHA512: 693362aade9e30038e152a43ea64f5d228d40fcb9cf7c9f25b477549ebd9f1da9b931d8647888cacb2556491f609acce8272f4a18e06ccf1c68c6e397135dc6a Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 522 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohpico_1.3.2_i386.deb Size: 209794 MD5sum: 4afa5ac208f437bf3fe675e1a077c54e SHA1: dcdbb59cb240f4972d37db16c59aba71879db20c SHA256: 07e9e7c682955a16c8107d06fde0e1aa467130a230f61247927a2afddb477699 SHA512: 814a5b6f6e1479f52707f5cb232018a30c09ca4909e6db01819f7e75e0eee99fd3127492f3e9e7bec08528e61e0a54a7bb34b0b70328df300da7108396e6666c Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.3.2 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 476 Depends: libc6 (>=2.12) Filename: ./1.3.2/libzenohpico_1.3.2_mips.deb Size: 164766 MD5sum: 6a8f954847d94ce7aaf43afd5c124716 SHA1: c2b889f7aadf1fbd06973c83271abd109d7c97c7 SHA256: 5e26cd276d48f5bb649c6d0e436536ad3bb644e53f504f8584b45a5ab5e0789b SHA512: 4c60328bc32bf751160dfcd3e85f3ed9bf305ff8644e376245945c4e300b381589fda3b9502e2364f118fded7d2a98773f4ead1b71d7c794d4df013b17b17790 Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15521 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-filesystem_1.3.2_amd64.deb Size: 3987740 MD5sum: 8144cb024d1b9fe874ca2b511fc5dc23 SHA1: 31d0c93f95534833caad50b72206e4f9c4d9d845 SHA256: f29279be9dd36e1a30e24f6e741236745d9e16c40321776cf7fe1303673bd7b7 SHA512: c4327bf5e472ef2119ca83839e36a7d31d4bb9176c502d707e974f38934e6901f185b8ba8c83191b4f4adeae634e4fbed29765730e53ffd31e8beb5dd83f7ab0 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14104 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-filesystem_1.3.2_arm64.deb Size: 3439044 MD5sum: 535a1c76533aceaacaa0d8573a056879 SHA1: 3bb429f018884abc1f8f025038c629821359e62f SHA256: d4b6c56d3285bbc37730259393de57fd59cbb71662866026a3b27dde40bb74f2 SHA512: 45656a50f942cd42fc16a2afb78fc1ae2c8b6e0683d8a7e1d447dfb525180e3c5b019c0c5511fd7aaee8b94b8ba0e8aba12f15a763f9374869fdfde47a654c1d 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13280 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-filesystem_1.3.2_armel.deb Size: 3390820 MD5sum: 372d95d0ea1a5b8f14808c626027573d SHA1: f5bfaeb71ed5ece2cc003db5ac335a02d97258f9 SHA256: c0bc01a0a1ab293b2bc1dfa9e6f6c1de53c9260f94e5405618341897f3bd518f SHA512: 8c37ffc679ba6e575a62f1dce8ed2842762b41d6522eca2664e47bc2c7603bb98e14ecc8aee0f70b4cfd3329d82a11b876062e388ee74f2edd236c3d82244538 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11241 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-filesystem_1.3.2_armhf.deb Size: 3506688 MD5sum: 24f7d23ce9d9e5b310ffad918d112290 SHA1: 83f94e6c0b6298b3696ce9f05644d89e2d696ec5 SHA256: f4be1c0106330b933c3c458622968f66e1e4eb282896f3d7dd429ed214355fd5 SHA512: d670e6273d71182a465748407a19fa9e2f25e6f18d6a257a7f3edcbb64a3f490ef5fb90ae949a6289de67eda0241474d4612d6dcd17f7533d93410d91df76144 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8057 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-influxdb-v1_1.3.2_amd64.deb Size: 2076660 MD5sum: ae98884d3aa95029c0430aa48b3f52f5 SHA1: e6985e8a6b3a79b59308caf794f02f1680275673 SHA256: b243d22b7b1190d894940fdd8ab02cf425dd88954365519d735404f243d1d79c SHA512: e51baa24853b3fd8036e6906f2f0548770032558a6d1f3c145facf3aed8269f0b90c64773cc719c7b4be536b6931431e65b1f808e34d232acd24795d58de409b 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8012 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-influxdb-v1_1.3.2_arm64.deb Size: 1902056 MD5sum: 16e42284151dec1eb0e5a2e9e439398d SHA1: 53d61231d7ec82c0addc5f30bf0030e8d500fc81 SHA256: 1688464e36e3fdc9e789fc7576551d88a2c5d63adeee6b6e894f143b313fabe8 SHA512: 7adeaa47c5ff80176d95b2b285c940e493c1051de869ad82c96283e9e967cc5b4433b7d3b4de113f11b79b794a1ac75b1b76f69476167534cf24bd35eb47e09b 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7120 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-influxdb-v1_1.3.2_armel.deb Size: 1730352 MD5sum: b8c121b6e68834a9c67cda28ddca01dd SHA1: 4dc721336cd261f3990f1b5106e176c5ba8d6fdd SHA256: 5acb2b0e664d630e3d43b3620923f86429d844b375b3643cb898e23c159d2244 SHA512: f7e6ef5c26b28a614f3205114738a084441ec40f7914df27c1ccff09885c8a7d28c023efb1efa772e6cc30860242e5745ac9042fdd506b37d7721342a90b13aa 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7018 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-influxdb-v1_1.3.2_armhf.deb Size: 1722712 MD5sum: 311377b708af7ea4beb541ece4767988 SHA1: 15ec7b9d3ad103fd9b055521cbe2c6d8e3bc95ce SHA256: 19c4b83862295030c2f925f524ab02001c10f478c7264ae275ca53ae9b10bd2e SHA512: c091a5eb8b9cde3ff96295cd4389ce9724fd2c0f34dd60aa1805970507944de49079893906e38835fa1e30f6fc8e337645cdfec5fc4c2d92dc748d3ef2be59cb 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10764 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-influxdb-v2_1.3.2_amd64.deb Size: 2792772 MD5sum: 74d93462f44f99a22141303ebf19cc41 SHA1: b583ec31409f171c0f6d474aa875f94dfafd9179 SHA256: 26497cf1cb486156f31e2fbfe3040e8cdf6753590131f6ebafa4a7448d51c22e SHA512: b2e56f42b558398ab074626a99ed181340a527459a2d7a5384da39ed365b332b95f14bf66eb207ce5f0f68ee3e92402bcf7da70608ecdb4161802a832b371ae2 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10733 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-influxdb-v2_1.3.2_arm64.deb Size: 2603404 MD5sum: ed042586ce6fe606cf75a6e368dcbcb8 SHA1: e8f8f56b4bb87ed47b6eb20c33ce19aa0353fae1 SHA256: 05e168ee2ce1a64abf93a1804070db76bbbcfe14f4731150a7bb88a93812880c SHA512: 9b6ac10a61e9af0e761c610870b5d1236f9a52878099d6b68289d2debe23a5e7caccc8ec013ee20a76cd203165b951d06f04deefa492416877cd917453990551 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9666 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-influxdb-v2_1.3.2_armel.deb Size: 2397676 MD5sum: dc5db3bbf5ec0ad6448357a235c365b9 SHA1: 2582da712eb2166276eca2cdc493cb08b465290f SHA256: 532ebef9865568d13f4ddcac64ea6ff33f506adadc071a86f460b35345a32f54 SHA512: cc3096dd490c35b0cac8febd1d2e59cd9636dfa229efbf1a1e30dd2fee9ff603463c505e0e21dd05f8f07c0c458393ed97c6fdc03d1b4e313b4f6bca91f35416 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9523 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-influxdb-v2_1.3.2_armhf.deb Size: 2415116 MD5sum: 48573b35622388883b4c26a539f84626 SHA1: c752436fe3fc79625992216421cad0eda767fa3b SHA256: a9cad1933e326820f51d082e55a8e09b9a4d9ec5accae534522e7c62c5c3079a SHA512: a60ef58e438aca515a80824e2c1a629227bb7b7de35988e85177ec82d9711bc76028a7c2baaad7cf7af657fb4f834ccd9c60a3665e7f6c64c35f8b29c29d6ac7 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14472 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-rocksdb_1.3.2_amd64.deb Size: 3767364 MD5sum: e2e9daa8d34e5898d4aa342e10a31ba0 SHA1: 0c39f934a0ed8086ef4c31e7652413fdc2e774a6 SHA256: 02983dc9960a718839ef4a2af53cb60e4ecc685d00caee2335894e25e4a2708b SHA512: 74eb4c6da112ffe03211d3e55ebe35312414c233a70b414b7cdaa957c1a9ebcb8c42527206fcd3887828e60483c88d29a67fca3ec6c7119d1e1c0be643777b99 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13025 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-rocksdb_1.3.2_arm64.deb Size: 3249320 MD5sum: 67bdeeedc227b3f9998f481d1bba51e3 SHA1: f9d0198c817421225b3cce5e06d876e2086ea850 SHA256: 51701e4276e6389be8e3b2df06cafb7cca164fbb0aeb296196f534ce644b267f SHA512: 17b7be1f31e42d8b61c76b7452c2da5dfc249dd304abe71c3c33d52c9cb025d17e8ef664d07a51cc4da477d6e07799a6c0670a4bcf3870737024b1639b9ef9dc 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12432 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-rocksdb_1.3.2_armel.deb Size: 3224264 MD5sum: c2e5e6afd507a37066994ff164d5a7e5 SHA1: d5a301a5758084addb89f17400a09ffdee4a9f6d SHA256: c61c9fe133dbf29a9b29e44ea5ec03d35ed52cf1ebfc394ecf56241e32530214 SHA512: 0b25ad9654280eb865de30086d72e1a4dbdb67d20a39892f166c199ed66b7d730215640aa45f5612a061b3dffe94e855dd99875991f28290b7f1aaf280760e9d 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10357 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-rocksdb_1.3.2_armhf.deb Size: 3338480 MD5sum: 84583780cf9c72c4321679e3f94a5845 SHA1: 52e34f1d634d61a873966a047d147c7f458e4417 SHA256: 06270210f2acc47857a68577a0f841e7221992840a920132684cf6552e261610 SHA512: 999d4322e87cc49827a079c1cb6aaee6157ab235b06d5dbd331a6aae42cba948db6a7eb88b5fcdb4f96f3a9e93b2ea6f2c742b3558c468ce029338679497b805 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20339 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-s3_1.3.2_amd64.deb Size: 4424892 MD5sum: 284580aa366524981bfc6e2c7fdee0de SHA1: c792b6bb7bb8b2f1e89b446c0bacbde715f30169 SHA256: bec7dd37e255e67535f5328c3fb5d0599df2123d181243c7090fcbffc5b2c7f3 SHA512: 0a7522dabb3370fb954af90a3cd80e7832e46ba7f51290c4f8a04ccf6dd1bc2d68faf742ac1065bf817ceef65aa03d22112d1b9d8e23be3b20598ad3cd560c05 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20563 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-s3_1.3.2_arm64.deb Size: 4200416 MD5sum: 2708eaf056b2fa00555475a0217f29e9 SHA1: 915bf3fc3ff9b592565c7a8c5e39eee42ec18638 SHA256: 7d5606545799fd32308f90599f77c341fae9663bfdd7cc6cac1e251c70f1f33b SHA512: 2c964d721fdd9600601bdd3c9379c6405feb3ff1d16068d5a7d954c944d88a0b2e0d525db53f5a139ef8f624a40aed094622a6569b7cb64e370134fbbf8e34f8 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18964 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-s3_1.3.2_armel.deb Size: 3907388 MD5sum: 1f23121b124c0d7c2d96da2790829400 SHA1: f283163ee4eb88a4e794dea49d6cfda8240db9ec SHA256: 07dd4c72790d5b1efe45ce1f419652aa8770bec86f2e88f02e61b7b055588b17 SHA512: 4f881a4d73c63c29c0d3d014cb3287e2e8500afd79374513255cb09560729351c30608198b6df17f359bf785ae98d192cf0b0931a79ea72ccb21ff5dd6fb0a29 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18712 Depends: zenoh-plugin-storage-manager (=1.3.2) Filename: ./1.3.2/zenoh-backend-s3_1.3.2_armhf.deb Size: 3945984 MD5sum: 5edab6fe1805480f9cde9a2c312deded SHA1: 7cf6d39db2cc21e0875683d06ad4e73c420b248d SHA256: 5d17f418820ef2fab3bf5540f8f9ed624035ca69bbd056b4651ec62b581227bf SHA512: 1d26d721215b584698179e8656ebfcdf1dfcfe2164ea3a65809c28ad9903c8993e88a07d8c3b3d3bbfea3552f7ef307877eddbaad6239dc98fd341ff16da88f4 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-bridge-dds Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16089 Depends: libc6 (>= 2.38) Filename: ./1.3.2/zenoh-bridge-dds_1.3.2_amd64.deb Size: 4641780 MD5sum: 4a3acb4d0b8ae99b3d3cfd27b354902a SHA1: 7841eb135cdae911c8ea0c74c5539b43582a75a2 SHA256: f9baadbaf0471862568b42601776b7875c242c92d6350648bf19d889eea9cea7 SHA512: 354bf795b02098af1ba40e7d018fc60b40f62b9b84006ddb80fa7b57c20482f6194c5516265608e664143f80b68667e5c87e502bb137ac750e77b49b73e07e1d Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14841 Depends: Filename: ./1.3.2/zenoh-bridge-dds_1.3.2_arm64.deb Size: 4148204 MD5sum: cf0388d88ee1330cb1c650f8a44bd716 SHA1: dee3e7aaac0a5ed0df5027980e098a60b4498c38 SHA256: 687fb746bf0b52221e197462bb9182553b85a0dd0e125553bab3b34cd0072771 SHA512: 48bf119e0fae3acff8b92158fb60ec8570a1dd93d420dbe5a5ef3b2b232c04aac93ed5a160cd57897719499773c5c78d826edc8a9453af46caa23547e0bb0d10 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15229 Depends: Filename: ./1.3.2/zenoh-bridge-dds_1.3.2_armel.deb Size: 4238344 MD5sum: 79dba4f83d91f77c47b09df022fb0d2a SHA1: 041e40f7e847706f0cf9dd7f2f60ef33a52d9042 SHA256: 5f74fe13af7045c188e99b6cb0bd882d5923daed922e629a9346ee289e59619c SHA512: de55d94b9ce86520ff62b729e04f270c185fcdc6816024e6a298e62ac8e5e6806f6599fbfb5f883375a9e46b9f37dad28d819edfda0dde3ef865c731f83513b8 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14684 Depends: Filename: ./1.3.2/zenoh-bridge-dds_1.3.2_armhf.deb Size: 4255620 MD5sum: 6704d6a67e99cac7f09b91bf796820b9 SHA1: f313ac2376c74086ec4d44ebc83be59f40edfb32 SHA256: 499a5186ffd4d38b7de68f51264f927fdc3515caa18eb6ae6db183edf970879f SHA512: 9fdd670b17aa05a215e35dbbe890f13a376e2a946584762bdb016014cd5acbe853bbb80d660121f1368d730d1ffdfc695603b412d4cd69cb724338b904198ac2 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-mqtt Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16025 Depends: libc6 (>= 2.34) Filename: ./1.3.2/zenoh-bridge-mqtt_1.3.2_amd64.deb Size: 4330152 MD5sum: 36e99f9b3be80881d6f840db4a7f54bb SHA1: a1bc385fda574e0363008c294c300daa42a69dae SHA256: ef01f497c13fac766e42bdacac35ad26e1503fbeb74f66c60e6dad0b104047e8 SHA512: e176be1b843c2f3e444699600f976d66ab8e88677d88379c794e59c1215b4597193ab0cfe51e91756f95aa66bcd6aabd46d40f08b8fbab0b73a5ca8011e4a2d0 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14742 Depends: Filename: ./1.3.2/zenoh-bridge-mqtt_1.3.2_arm64.deb Size: 3856844 MD5sum: 6917d6336cdd672e75e66dee3b6e0f3f SHA1: 92b697aae81419e9518b93b80a18867680b7252c SHA256: 121be595fbe3536c143e3dd0330d839cb9505b91cc70bfada1faf4e62fa2eb0c SHA512: 1d46ee0e796550872e9ee0f60730a330cd5bba254c0417dc224c13299af4260b28a9b5e165fc57c590338469ea23bacf9af467b4eb1c118fd1ca87cac142dae9 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15323 Depends: Filename: ./1.3.2/zenoh-bridge-mqtt_1.3.2_armel.deb Size: 3968812 MD5sum: 60797430c18b682970fedf3a4cf4907b SHA1: f2347dc0fe9657e4f8ea7ace229344fc359af648 SHA256: 7b20516697a0889a9abd3ba9e351762f5fce1f9c305d9135ad5efbead935e85e SHA512: ca653967c8c0a1a2618a4974f842a1398beb8b5292a602dfa82dc8f213d33e11c672de524c6ca16f830b5a346e16ee58395a53433013b1cd7773e607f3eb4b63 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15000 Depends: Filename: ./1.3.2/zenoh-bridge-mqtt_1.3.2_armhf.deb Size: 3960852 MD5sum: a038690529ad2498f4a98e0079e26947 SHA1: c3f0599097171370c0cb11513f2baa1b535433fc SHA256: 228f982e44072e0f0abf830ca692b8b7116f98441386b27938db931e861d7160 SHA512: a5ba818c4ae36251bb6a0d5431539c32c96a8a35ef1a5ca192c8c543421e108457823af42fe6a19b2a224b4c6275f81a3b01216b1445ff04bb49088bc7a1027c Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16718 Depends: libc6 (>= 2.34) Filename: ./1.3.2/zenoh-bridge-ros2dds_1.3.2_amd64.deb Size: 4764220 MD5sum: b60707006903f32a9e9df973359af65a SHA1: f876bca42dd1ab62e50d7d4c13db9c0ff370d9e1 SHA256: f1779a42496ca1a6059620047b77aecc21473563f4c9357c7d2bdec32a97fbb9 SHA512: 69fd5f8ae9d621c8367efdd1ea6baa8f1b7484a504e1600d52fb5652d73e3c7de227c13013493894398c1c913c3187ca2ed09d99fe754c006869407e9f5dd64e Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15407 Depends: Filename: ./1.3.2/zenoh-bridge-ros2dds_1.3.2_arm64.deb Size: 4259960 MD5sum: f0e38afefc789c53b776a895e301858b SHA1: 6ec104abd7ca8c214ed71fc2d3f39acd56d96421 SHA256: 208b1948b3aa84db3bf45933975a1ffd5229fca01dd07ff9cb7b1963ab7f1d27 SHA512: 4dd548dbb410420dfedc75669c10ceb2d61877ff4375c52ec9e078aee5194bb2851682bebd951175573553b253982bf6c154b2b997dfc81e802b3e3b17eaa62e Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15772 Depends: Filename: ./1.3.2/zenoh-bridge-ros2dds_1.3.2_armel.deb Size: 4355884 MD5sum: efe38eb4dead165699eff888ed65d461 SHA1: db815cbc9a5f8cdb953d46b74ee43910057bf1ce SHA256: 79360e7674c5532ac76a5f10dbd72f43be3a8e52b5575399a7704fcad5899f35 SHA512: 6a52092d9fbb714b52eb1dd3cd9effabde9632f3abc11807418f8d46da7bab842a2459cad90692245a2154f4f1d50a083921fdbb013ec11b78765cd9a9a4dbe2 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15229 Depends: Filename: ./1.3.2/zenoh-bridge-ros2dds_1.3.2_armhf.deb Size: 4374880 MD5sum: b9bf350103cfe7ae0f5ff7c0c82e315e SHA1: bea82377c85058f73db002fcbdeb2fdf174f557b SHA256: e0f8cc9388b23a1a806e114263423aa44e99a651f7a02f6c103299c87c212ed9 SHA512: edbaee42e76c826c8b42a2164be7d8e07a9fdfbd815e4d35860bc4aa115265af1fb54228b6f26af8e49cda43ad5fb269ba6c09bbee0321aabf16bf6903569d91 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-plugin-dds Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6329 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-dds_1.3.2_amd64.deb Size: 1708152 MD5sum: 77ab77004ef911b59b48783fba023d65 SHA1: 5d0c9d48a4dad9d3f87c6bfe1da3eca0625dd02f SHA256: 8c8a5575f827de7ff298fac25b8877b7d148053472148438760891ac569e1d68 SHA512: c3d0e0d1e84fbf39601a9ab0e091525eeaa89a1a965cc59c6edda85cd21659c95528d49be7fdf9caaf9c6bbd9dc65cec6ef07f913e7d41eb2e1a114e2e7045af 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6261 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-dds_1.3.2_arm64.deb Size: 1557268 MD5sum: 9ab1a4c7b8613ffccc5713f98c304154 SHA1: bb3de60f8e519205720ba7b410e6fe4864c36ed9 SHA256: 694bca906b2c7aa83d34d03eb0b73a0db2d7466edde103fcdea6cdabb3928b6d SHA512: fa25f7fe3622ca320ca5f147f11d2337f4d7c879dc3e1b4d9785cbb1cd95ab11cb6e903245e5befa52e8b374c38df4bcc80b3b0c69ae8b23b4de7f46d8dfef3d 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5831 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-dds_1.3.2_armel.deb Size: 1563936 MD5sum: d8e73c8d5d399134cdc7d6e005092478 SHA1: 47c1f8067889d7bb7331e88d28158db0b1d3d3cf SHA256: 2b9d0992f1cb495bdb209a1cb5c2a433761b316e6185ea55082ee3c0160c7efc SHA512: 11f2d73b0d9badc74605bfbefe0ca50ecdf00d20e67018bba17363f2434f15f9258f0c2f049f0b5b1e0f0efc4e932acf1cf79116f654212cb58a8a0f31afa04e 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5484 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-dds_1.3.2_armhf.deb Size: 1578732 MD5sum: f7cbbe1e339a8a7d0f747384779fc2af SHA1: 835b93f0cda84f092c6d71af2ef320115fca430e SHA256: dfe09274ccb1aab3ec84eacddabb17e5c55c8acf180ba8ed678ebf6ee62d8345 SHA512: 14599666f4b6f4e4e17fab233a842ec74c258538b23a917eac1177e038fc9d795abc492640d6b2282c2e21d7ee5dddc3e0feec392da507ca9343343e3aaf3596 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-mqtt Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7682 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-mqtt_1.3.2_amd64.deb Size: 1924232 MD5sum: 6ff4f4ea4a5785dff065698f2865da90 SHA1: a499c7f459732d252960ebfdf9f39d1475b6b5fa SHA256: b355a50aea9b09b76bad2fedda2647b7f75943d6052955b615ef234aaf0fa2ca SHA512: 919901c681169633e60ece27d7f57398dbdab3648c277355bd3a5f37d7f91b1a0117cf9dbc7404e876172259eb6dfca8daa02ee99ef0127c97cf7bc23ab9d8a6 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7449 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-mqtt_1.3.2_arm64.deb Size: 1749104 MD5sum: 929860bcb84391b07213197be92dcb8c SHA1: 8a00147dd2d14afade2aa4b5d45beee4790904e0 SHA256: 3d407b2d8f892a11028bfa1937fda4e0f8d6787b592428317528555438232eba SHA512: c8b25ebfdbed063dd81f62d9bb9d282d9ac1e271049232fc671d4640a3b7aab383365f6df0d09f6dad6103a9320cdfca05084d2620913a49ab288f4933d46f92 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7062 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-mqtt_1.3.2_armel.deb Size: 1633936 MD5sum: 655a796fb37e4701868f010ccac059b5 SHA1: 1ce53b236430a61b2cf436341e95c15a1004b8e5 SHA256: 4f684d0cf91fa06dd484a264198c26257f8e4df8c6529c6516c5666e1ab90b5b SHA512: 78eccc1414b35340833b3e6366f0061fe13097fd6458a08606942df199fc1db4021c15ee0eedeb81efb485eb5debb734c353f856fb5cac7997530bf29e52a0f0 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6901 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-mqtt_1.3.2_armhf.deb Size: 1643332 MD5sum: d93ea0d6a470609937689cf789afecec SHA1: cd43cd0af367d5ceb7702cc9fbcf072153c2ac9c SHA256: 24b3ff8ed3ae2cb2c18674bf4d99ab1b2b5e6f7411aee69fcb1fac40b29d2e77 SHA512: e71dee1fbe7dc6fe04550241162e784ab6a89709a2484588be2b9a074600eb71321d52c66a3c99f360cb8bb157679a94d442c8ccc5d1cab260885fb7b0e6dedd 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: . ```raw 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/](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](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. Package: zenoh-plugin-remote-api Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9794 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-remote-api_1.3.2_amd64.deb Size: 2467580 MD5sum: 12e0c545016dc843a2051c6e35958418 SHA1: a08f3950098f1a1dc24387d2f2000deb92b0a77b SHA256: f7568382152389f36be028f1ee94393bc7e2e46d4a2cd7a8a051fd63c2d935f2 SHA512: ff71505364234524c50a34e1eccf0dd536fa856896366d2ef1a93ff2e3a7605bc510e37269f9025b49a82970b0179b9fa9283c1205665fefb5dc0c2a8fe2ed2d Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9806 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-remote-api_1.3.2_arm64.deb Size: 2291436 MD5sum: bc3a25779e66caaf0fd9b5cb13a0025d SHA1: 6982c25fd6c09241144d1503412b73cddffd406c SHA256: 8f8cece86ea8d04c296b0bd3aaf5e859797b2f2200597beb0b4353ae7b43304f SHA512: 8030a8729985ef25e1a68a69c7c995f8699a95f3a830fec99179ed4997f45d2e530ca286fe88ff50146a986f094602a150b45db50192ff01e2e269674101f048 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8808 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-remote-api_1.3.2_armel.deb Size: 2060116 MD5sum: aab2e6a3dda519aeadfa2a926a624ac5 SHA1: c204e01cfddb809867077e3dbe0beb28a14976f5 SHA256: 9a7c83cb2a558a3b6bc4d1987a7cd6d5536c193330be668e2ddb8f06a20fee93 SHA512: b3b1f96f7b0a5b37ce183abec29098b945130594bc0085e8b2b66fb85acd92652a8b1a4afa2dfd137a33c683b63d69235bf00f7d654c6e3f13c5c7cc8af7d54b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8636 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-remote-api_1.3.2_armhf.deb Size: 2068456 MD5sum: 35df25e2aef8618c50a9e2fc5c04df65 SHA1: 7d2ed426c6f5aa73866a9a4ca0cc4df2cac8e9bd SHA256: 5b33c25ccc98bc8be0f21a189b979cfad0567d9aeb5866f3e19d6909d9e6f21a SHA512: c023b2c48434e3eaa39af0dc449efb2bb39d212688f24b53afbdea4f3f79aa36012a3c81671441330801f48e76f28e9a850a494ff9b75b74d3e4f63e5dbda036 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-rest Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4610 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-rest_1.3.2_amd64.deb Size: 1241052 MD5sum: 0c21e4d59f0bf2fe97610d7ff110066c SHA1: 75a9b773f912653bde4d8b832f6fb3eccdec715d SHA256: be9f9435df336b90ccfc4e9325320522ba7e05f43aae299dd00cc4c073206deb SHA512: 96620466b2daa467e888991241ef6a9c34a9e5ebd8f235dc03624d9e57fc48b29163503f8a43b371567007cb75ecc1278a1236c0c931daa68a97ee4b4d35f292 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4658 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-rest_1.3.2_arm64.deb Size: 1148612 MD5sum: f2da8aa1f8b32d222858162615016fbd SHA1: e8a956cbf13eac0fb02f1a8ce6b07db26d41d0a4 SHA256: fb9ea1d3d89fb83cd89ec89b61b4c73ef1e77760699186aac956993a35a41e06 SHA512: d5f30ec874b4330c2def127d5178001f7c7b81597da73ec7a955421b1d725fa08a239224fe728f9b33c341b8141955f80e3a2e0aecae1b86f3f4eef2217201c6 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4384 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-rest_1.3.2_armel.deb Size: 1185144 MD5sum: 014ae530561cfa82a2611e2af1dbf1c5 SHA1: 550df4420f822fe7199fee0ef40dc81df8528810 SHA256: 6c69c6bc4e9822e2e5554b7cc53925a898c4ed76093ebf4c013dccf27f28674d SHA512: 668d2b3c8b12b57666d16407f1e2d7782036cc8e3bbf0b7167c3282c9f35f83d98a43cef689dc22a92e356c15bed555c5584c273e52fcca9a94019b69205d3b8 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4311 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-rest_1.3.2_armhf.deb Size: 1180072 MD5sum: 93b541ff0ca7dc271dfe27c38e7440d8 SHA1: 2699cf904f5dbdbeb9445d7a0d7e1c4616823092 SHA256: c28e9e57f5c23c2b70bbe0032dd10a096fd2fa909f8eb2f6b0585c268875b27f SHA512: 9d151208d92ff37979461180948d5a23ecaaab0436e5d9fd155d6fda110f9dbde9b529acfc3e890b2c0d8750f2497a46e62efdd9d607f1300f16a9c599700248 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6897 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-ros2dds_1.3.2_amd64.deb Size: 1811160 MD5sum: 47dfd7718cc816e3aac5790139cbf369 SHA1: 0b977b6457b81f4d4973dbdf7eaede0766db9244 SHA256: 8c67ae0a2b54daeffa2af4f7efd9e4d722345a999fd28e269816ec99973a73e5 SHA512: 2b240703443ab6d5d0c87cbe4a86ecb973f8aa33e1dd1c7c1ae470cad7a0172d7dffc6858ff7558a418d12d1b094f8b8be38df576e5d773a87b8d76eaca3ec50 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6796 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-ros2dds_1.3.2_arm64.deb Size: 1652844 MD5sum: 540d8b8df36031c8d61e8f2b923ce8b9 SHA1: 8e37c83b89539dba6ced2faf2b6044d7c9df1f61 SHA256: 89c7d52034e4ef160266eeaa7097475d54207922af91ca18b1e9c279eac70397 SHA512: 0ef2ce7bf9008fdbf4148813d2f1f2bf81a2f2a2e8fd26f96a9598736f0c88fc539fe955c2c98d332b37ee1c4bbb0e265bd35e60f6ead7e52c2e662ba4d61e89 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6338 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-ros2dds_1.3.2_armel.deb Size: 1669988 MD5sum: aa90901c43cdcb884c3372a7e21d23ba SHA1: a627901e11014f56116dc70942465d2710294476 SHA256: ee401719ffc25329751e471318b393b0e5a6e86676e60fe8536d69dd010ae342 SHA512: ad4410e3e7ad6bb5a54662d3113f5b9d6d724744ae90fb2496c00837fe4821d75c7cbe108cd2d90d5d1c41ac07e7c7facf41db23c1897218d5eefe74fdbfe8be 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6002 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-ros2dds_1.3.2_armhf.deb Size: 1690148 MD5sum: 262fa76a92bddf918ac3436c83c745f0 SHA1: f91842f9fb2c86d6ee5b86b7de387896a041aaf5 SHA256: 95eb49c660972db466058bc4e43d3d51f4a6f7268b7bc5ae5789b01c343d1150 SHA512: 3215803940242e256a88ed0285db3cfeea6219e0df415e740b9008c3d996785b5d72e5265b58f25c6b3e73a63a639c34ef5699baa5f3a36e490532a190370fde 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4353 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-storage-manager_1.3.2_amd64.deb Size: 1133624 MD5sum: b828832d2521359892f56cc7f0cd5228 SHA1: f3e5756c6c2d723a652dab8e37da9efc60438129 SHA256: 4fcf52dcd4d7093805d81308ecb7bcb18b9024281001581e832a0f6d5e14108f SHA512: 7d52380c2f8ffd4fd3a372f7c190ed48115d404ff0e5ea2d2c2f7ba91bf4941a506ccd3f1526b7e4bd973fcf2f55b23a900348c4a3dcf7a4388743b1fd4296e4 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4386 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-storage-manager_1.3.2_arm64.deb Size: 1051960 MD5sum: be0461029c576a0c4f792098880eba9d SHA1: 366d489bff5c0480ca09af4c252cdb07c44438bc SHA256: 2a07dab262108a0c0cc01bdb2bf17eb2b03616f2156effa0e7b8ca279d05fd6f SHA512: 05c01d42d0fb0c8bb8a2bca6ea19b97033cda706775cde5b45106fdf04f55c750b8d8e962655712090b19f0c04933bf26eeae0b12a38ead7302fa12d10e37827 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4129 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-storage-manager_1.3.2_armel.deb Size: 1099720 MD5sum: 1dd01fbe3aa08790155670b562bd2cca SHA1: 4eae8bd58ae6373e3baa51f0b7ac3acb1c43a0bb SHA256: e806a5c2e8947323389d6dbf2f189f0b1a3eddffea6542d4015675469d44e5f3 SHA512: a5164363380cc17499696cdce70fec203c13e5a366b6df08b29220635884177f2bb0c35c601280f69703ffb6515ef78bb31bd4ccbcfd5a15faa0cefb80506051 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4040 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-storage-manager_1.3.2_armhf.deb Size: 1092732 MD5sum: 52291f62bdecdd38b2f9bdbcc2944478 SHA1: fcb14bd917cf835ac8c8f701d13d9b628c6040b7 SHA256: eefc5c40b2a81e39615e060c287e16ee63fb87c6bd5bd47ded3cdc875d92604f SHA512: 8a6645f07e7634054f058fec084b94e95342b9f6e254732b4c0366fa02e8e79a0ca261ecac87ccda3830196e4ba28c705b1ab6a6bfd17bd63cb506827dbe52e4 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-webserver Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6960 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-webserver_1.3.2_amd64.deb Size: 1654984 MD5sum: 903230264fe8ab8b1299b5e0c0eb0b26 SHA1: 1418164b9fb0ccf2186c36d6150793aadaca3915 SHA256: 00d15789d2e58b4ff279e8771192c52bcbbd7fab409a0f93747365c3d12a3710 SHA512: 0b030bb7507e9e7953cecb05f4ae2c9de91c46d55205964c710529e8690be36ca95ef456e12280a4ad6004991262fdbcf4d7f38bebad6a16f25e3b98cc9140e8 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7157 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-webserver_1.3.2_arm64.deb Size: 1553112 MD5sum: cd0a5102b66ac7f71e2a3a5b14f9058b SHA1: 2b09d0e86edd468d394c7075189b164b4d85e6c9 SHA256: 0784e96ca9af91eb12a8748d2611100b4489ae1c9a25bd7e674ab9cd6a1e2052 SHA512: 35b1c9c97da05aeb4950ca2bc521427a90f43dc30af84a16b36aad8e6f21a7d2c2c7ed9abf12951e0222222934337af41879873f91614fd88f44f9e0f3cdb4f5 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6482 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-webserver_1.3.2_armel.deb Size: 1523184 MD5sum: fe37577d901c00e2a4c98cd3e97a11f7 SHA1: 44c3875a88a4fafb78a5d1c128b4ac1a02e20867 SHA256: 6f92f3d4eda2021f0d06c0993e4f5aacd30eb3771acb35663bda0ed85f3c6578 SHA512: 04b842049cb52eef3e8631fc3eb49fc2654fdbcad52eb16465afdcddefb6169a6ed230c82287a9261075b9d26e2ad404dc53323bb5580c3e4b5c9f97d40d09a6 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6381 Depends: zenohd (=1.3.2) Filename: ./1.3.2/zenoh-plugin-webserver_1.3.2_armhf.deb Size: 1519272 MD5sum: 38f85370b09660a8b7a2aba5da2cfcfd SHA1: deb653f25fb109dbe5a930f0b9c228be4a2f4330 SHA256: 3da7cdb058990b5e2102705c05eec901aadf447420b37325dc4967e9899cb2d1 SHA512: cc5c70031fd9bda3d2b7d09fe5cf91419558aac814a17720e4be87ce823b700c49e7f5db80487a57b6723eb397f296491b496c30959db66fd780eebb0f1c65fa 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.2), zenoh-plugin-storage-manager (=1.3.2), zenohd (=1.3.2) Filename: ./1.3.2/zenoh_1.3.2_amd64.deb Size: 17556 MD5sum: a4687ca26135b0831288af5d9a14964d SHA1: 8bc936a97ead75dbabadf400a11052f367043d78 SHA256: 6553b2352cb5599b3742a6793fc04d30e8a6425e11bc45313d17c1fdaa0c5183 SHA512: ffbcdc009e64a2937a3ac3534d746fcc994fa95e47933b8c2fc33712fb33c05c8da855bcf78aed54856fc80faa7d02f96d8aa6bb8248b6d28092146380ae7f80 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.2), zenoh-plugin-storage-manager (=1.3.2), zenohd (=1.3.2) Filename: ./1.3.2/zenoh_1.3.2_arm64.deb Size: 17556 MD5sum: b564c73502afaaa13aeb559d06672afc SHA1: 84126a331f7e530610608c747a4aec7b37fb0fba SHA256: aef5c9e9b5661592d5415f0af290e1dbb27ddf1fe45c12cec8967776c1cef4fc SHA512: a74aaa33ba1b7ee0347d70c56a6f6e8080572acca8b6d8df8de2799ec518f8181f76972fb03614d73eaf883f0ebda13cbaba0dd86faa4014d7c5ea27fb7bd1c8 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.2), zenoh-plugin-storage-manager (=1.3.2), zenohd (=1.3.2) Filename: ./1.3.2/zenoh_1.3.2_armel.deb Size: 17556 MD5sum: 8eee3aee61be95a2801bcfe7685fbf2f SHA1: dcf11e5eb00893e9728dd7878b88866f6ca282f8 SHA256: ef140ca7a85f3de0a7b5cdc74ce24b6b03239ad7a752c3899dee47d62d40e6fd SHA512: 3894e9213d3552430dae02c80c9cf2bee62ae91aa2ce861c6e8de5e264a27db40c65f830161595d6fc9ae2725310e3fdd74e7e794a49140c1eb802f62da28146 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.2), zenoh-plugin-storage-manager (=1.3.2), zenohd (=1.3.2) Filename: ./1.3.2/zenoh_1.3.2_armhf.deb Size: 17556 MD5sum: 0d5b16e8fbe2e1b0f35630f3dad0da80 SHA1: 1ac838b3906993b93d790280f51a55d4a69a944b SHA256: b99f4ea6826bf78de32300ef74ea0777fe5961511871991e5fd78333dd637428 SHA512: ada8d8e17d5589630d2f0caf590f2dcc134fc60bc88847ab46462f79b01a9ac2eba15a8c2bcaac30071a2e126e6aad40dd075bea420a7551019c476074062b84 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: amd64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13908 Depends: libc6 (>= 2.34) Filename: ./1.3.2/zenohd_1.3.2_amd64.deb Size: 3847940 MD5sum: 64cbe99c60a356cd6b1a4570fae6dd44 SHA1: d3d83c351b3cfa41821c78fe0600330f8c8b4567 SHA256: 938b5814370dbf1e630be43ae8caa80d77bade77a5a6092a1de8b5e2c9dd764b SHA512: 1297481fb1141d42be1f67f84ad6413c34fdc1cd4adfe94d2b5d64758b5d243dac05f1a002f62b446e5d2b53834513b684b29bf860a4cde5410069bfe5a163ef Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: arm64 Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12556 Depends: Filename: ./1.3.2/zenohd_1.3.2_arm64.deb Size: 3434584 MD5sum: 20f4ae27f9bcb3783ddd97f2e51a2a0b SHA1: 95de282b6fd358e9404a092d013d97e75d70ae8d SHA256: 8efb9d0f9b0993026845fab23aa66d214bb8633bbec6ad5d62c12c53c8d82855 SHA512: 20b30269bd8ad786b737fb3fb7874998ffc0a507cafbefc1ce80e6e700c9fbcb8bed8b9def2c938795d7b7fbabf1efc817f3fe17f91c21bc5ded45fb11a798cf Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armel Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13210 Depends: Filename: ./1.3.2/zenohd_1.3.2_armel.deb Size: 3598020 MD5sum: 370282ba20f774afba5d0a36bf024057 SHA1: d1047df3e04711c7ba86eb2f973789cd0102f1b7 SHA256: 8a7d7816466ebbf70dfb56d25c8b49012e6006c557ceb9bd5c5d1259fbb07a01 SHA512: c76d79438e03a7db4cebf146f8a3a899e9fdabedca69915961bead91ec5b5a7540f7a192f15d83f82ed3e5bc4697310ab74707fa2eaf8cf44332d606efd235bc Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armhf Version: 1.3.2 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12935 Depends: Filename: ./1.3.2/zenohd_1.3.2_armhf.deb Size: 3619260 MD5sum: ff5a747571d018ae75df41647589655b SHA1: c92477659003e8e7795eeadc3842b7aeb7f0884f SHA256: e9cfacfa0bdcfae9fa370f23cb25e7e8160c0bbaeb80fe641ff0d27429587d09 SHA512: 165ec52e34841b26bdfe6421da2e3ebd64ec8437c71e80c11d5603a1765e994e136cc427f6004b10015ef2347e2070e3f48d3f0ae3e3f5bcc92b0f9badbc91cb Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: libzenohc-armv7-dev Architecture: armhf Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30737 Depends: libzenohc-armv7 (=1.3.3) Filename: ./1.3.3/libzenohc-armv7-dev_1.3.3_armhf.deb Size: 9540136 MD5sum: b174563fb23386da97d7c1fafcde7e03 SHA1: 97920cd48515745b74a100cc95720b7a86782124 SHA256: b795956603f13cd1f24158e8c6684e0d48aa962fdddb2156750dd6616b58aec5 SHA512: 3b40d63bd08089e460228970e792cea9cd4cc1a53fac39b3f57eef55d96035a69823dcd7cd0f3a570f6e198d7c51969caea59a999921a115fa2a2c3431df9a93 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13479 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohc-armv7_1.3.3_armhf.deb Size: 5681478 MD5sum: c85518e3df428eaad8d265f05d4eafa0 SHA1: 9df986c6f053751a06594c50ec39d0467f34fd02 SHA256: 3cc77f9741d11c1da9c1c5bd30d96f7d5b2c29374f14daa6ced139519ea3e96d SHA512: 01fffafe3818937635b12cc37ecce1def221cc2dbaabad1208831ee5230a602eca67e7c88528069517e08df635ea6d48f065b84d22661415eee871d0d14fb860 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37331 Depends: libzenohc (=1.3.3) Filename: ./1.3.3/libzenohc-dev_1.3.3_amd64.deb Size: 9157630 MD5sum: 5b42e9f4853bdfafc5583049aee33371 SHA1: 9c373efc6f47d18298636ad6eeb0f3681328d515 SHA256: 20d2699621a01b7054a010e6d975ad7542d510bbb000dce455b67cbd969fca97 SHA512: 57cba327c35d636b38a88d07dfaf058d1b70eb6aba2c7724694ba0bf7312ccd0ace34c347ca588ba7d400e4bd37bcd84bab66fc7c2a2107202ba5c9f4e84f45a Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 36669 Depends: libzenohc (=1.3.3) Filename: ./1.3.3/libzenohc-dev_1.3.3_arm64.deb Size: 8822784 MD5sum: c5e0623a6967453a7f210e5fd6acf47e SHA1: 43e84ff32bc440473eee1d91928e22c396ddf1df SHA256: d9dadc80e28c80c94b86bbc5190c2fb1b7feddde1b17c95ed27995c5040f8b57 SHA512: 5b40b8a03215432a0cc58827d5a32c40c8f112c5ef36aca9278974e14c6aba89fe83496ac0f029ac8101cd9c31134ea17314a71f1eb5058f1002ed6e132065fc Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30916 Depends: libzenohc (=1.3.3) Filename: ./1.3.3/libzenohc-dev_1.3.3_armel.deb Size: 9598102 MD5sum: 0ad9bf803e3f5b03743f0b2c309b6555 SHA1: e1c65e2c8e530260522333d4018ef5dd0d796f16 SHA256: 4b602203eff2c4b7000d25312640f64a1178e93f39c9792cf3b4aafc83a91f6d SHA512: d0fd886a5321d9f16989a64973f0a9d130ae52e04c71d234f622c097ea1e8e36c8cfb06ab78dd66095750ee50c2fae8f3de63feb533d1e54f73e4e0c4403cecb Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31061 Depends: libzenohc (=1.3.3) Filename: ./1.3.3/libzenohc-dev_1.3.3_armhf.deb Size: 9727058 MD5sum: 5d468df572e44609f3bc8e9c993e3aca SHA1: 0c84dea4ec29bc7628d06d07fdf8d9e3de411fea SHA256: 7f0f10de5ea7066988342b68bffc7d973bfe083799ef16c2f5e6fad18b0bac41 SHA512: 5b15928cf95bba48f42d5089be3e445480181050f6eded51cece61efd919d4164d0e4d4261b336aae57b2cf0b203504a98c24ae1f0d1507507784522334883f2 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 35107 Depends: libzenohc-musl (=1.3.3) Filename: ./1.3.3/libzenohc-musl-dev_1.3.3_amd64.deb Size: 9028150 MD5sum: 94a3a76adab35e96aa0c307e9fe32597 SHA1: 9950985373a299bc54a5686d37fc411a5b68d805 SHA256: 76e7c44e013fbe0740a0366515389f5abd402d50ad78db0bd2a6c1e295d50554 SHA512: 37552f4b2c257b12e27ca92e714375b67bc4fae4bb4809582c10a3ac45ea5d924e51ebd8de79bf1b2165f0e58cf890b29ae2c4aa3efa1e11e97cfbec999c091b Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 35978 Depends: libzenohc-musl (=1.3.3) Filename: ./1.3.3/libzenohc-musl-dev_1.3.3_arm64.deb Size: 8692066 MD5sum: 95df21d544fb7706c9bd05b7bcc7e2d2 SHA1: 694cba4832653a05999f61030efaef793e184170 SHA256: 4b7eb98e731adcadb88ba719e95b24bc0a61424eb7ba417194cbe3c06d565df8 SHA512: b368fee889bc1878a9648ead74d79333fc74da38167f3d9ec6ddf39ebe51fab57593b9dfdfcd24efaae1dd75a7bcd6b725ad0d9bf4c0847bad44177444b4abca Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 14339 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohc-musl_1.3.3_amd64.deb Size: 5697398 MD5sum: 4e0c106ca079d0a9d0d41bc41b70193b SHA1: 6884f7ee96a8f5dad591adbf6cb7d319328c4542 SHA256: 46673c1a5164eed95de14b716dd67c1d231a2fb68d9e44653320153f629a2af1 SHA512: d613a54372b47579b4aa103c2f96256daac4f5aeb5ebf6356f983ab6b4a636b7c55e3cdc7058a3bfe701e9914e750ab1c92908033f6fa870ce2d16e9ec54f3df Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13356 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohc-musl_1.3.3_arm64.deb Size: 5416514 MD5sum: 7d09c93ed6958b4b93f1cb7d9cbeea72 SHA1: 8a3d165cd9813d90f6ca0a5d4e4016d40a45f3e7 SHA256: fe1f1ce2ec7a41d2db3ab0a1f1e786c14bd6664e1bba10d7d1246b0fcd889303 SHA512: f51d15d0f946c3e13679973acc2b49da43e018351cf9e1ac44f55b49e2420bb36e751171bb8c1021ccbc73a5db128c022e876530db95e2bd2e9610278ca977bf Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 14341 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohc_1.3.3_amd64.deb Size: 5698424 MD5sum: 89ffa53b3d325846f2aacc0640a8541c SHA1: fa990fa53899e0a8be5fe25709f284fb2d406a23 SHA256: 620d9d2527e8dd6bf1aaa3b4cedef43feb2adf1c2b8cadae1fa0b1107b3ec4a6 SHA512: f726fd4da9541c219fc6be3c549c9bc53c800bc6d2d4ce74bf131d1838ea3c2a8530fbd03b1161b95047dc4ccf2269f70758502cdd9e6ad8cade98adabffc9fc Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13354 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohc_1.3.3_arm64.deb Size: 5442814 MD5sum: ba37ed161799afe1c78470913aa69f43 SHA1: 4f74b60442be75ef51c5a70f89e63a895a1dd993 SHA256: 9a7581a860c430d3d4d3f2fcdb089f2c3f9f5023d918b1e1947d3c14f8fa8696 SHA512: 3ca50d0764caf86f02f212ecd4718b9f0091806657a13a87223316d59b58b7547e66177ba114a1ea32f377d6a711fa0a5f1c1622d27fe7f707b718d0243df913 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13725 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohc_1.3.3_armel.deb Size: 5749062 MD5sum: 18de092d0b2688fbcd1beb9b0aca98c4 SHA1: 701d8ff2d9779db3c56d18fbb69fe1854e5c42f5 SHA256: a666178f43e363f0e35c62dd29a05419eeede3e86d89f42a8900716197e91fe2 SHA512: 9db8adedf6e6bbd7cf40d6f2e577a5af566e4b0a1587dd2a37a67d59cf0e0b836a9faa489a58671a92d30a17e81c874a95a682938f340d70af84dfe3190388ae Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13730 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohc_1.3.3_armhf.deb Size: 5823258 MD5sum: c3fd3e47ee419bb7465237abcc61d8ae SHA1: ff005aec3b7606d9d3022a0ef2011283e637da84 SHA256: ba82c1cda648dea848eb9aebd2fd0310c26fc5a0dfc9f78b23529c4872dfcc53 SHA512: a42c7375ef4d830e66a5cf682f039c1246d717bbe2dc5c2e57ef23f264051f70edf4b5186250e560e04e40b7504f49b7b29160c1575e3bf38d333289309e2881 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 450 Filename: ./1.3.3/libzenohcpp-dev_1.3.3_all.deb Size: 57998 MD5sum: 87c33151a023f6ae3b0ecc203302f345 SHA1: 60e026a376cd724bcd3fd286f8f43b6f1aca8d28 SHA256: 866cb6d0c25321f2ae090c2135dd46d3ccffb4edff0ece2ad2686c2ecb9c4a2d SHA512: 244039be35d3d1548b29bcccd2a5037800ac097c442381b095ef07895399fbe40871fb6d8c237402024d2185685ef76005586e905499e872b1e4482e35c55336 Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1257 Depends: libzenohpico-armv6 (=1.3.3) Filename: ./1.3.3/libzenohpico-armv6-dev_1.3.3_arm.deb Size: 252614 MD5sum: 43bd4c347b5466fb3d460098c056ef33 SHA1: c8275ed626c255add30dbd78a0dc15fe280a1439 SHA256: f3be37f88a44caf3306f90943e2914cf356e43c3676af0a3af8c1f29493da3eb SHA512: eefa042deb3b16f6e07e182088de5a8b89bb1ab106fff9552d9e8c6ea9fbb095297ee9197169f7d19f617fb235e8bd54fa23e4ed9d9e20fb16337ec3cdcf991f Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 364 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohpico-armv6_1.3.3_arm.deb Size: 150162 MD5sum: 3469657bae3bad4e9a4c777ef58eb062 SHA1: 33d909e40cfb9ab56af521883f708c93d47e61d2 SHA256: d0d982e7cfd03f3c80d3268b9a1ae2f89ca118869dbe042d75d9dd295302bb9f SHA512: 05f668601346c7cc52f51b5b58c6e0577ee23c06c941fd9426aab5881ae74e90272fb066d23bb20476518bb4fd51af280eddeb21571b28141d7e8e1bfd9625f3 Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1250 Depends: libzenohpico-armv7a (=1.3.3) Filename: ./1.3.3/libzenohpico-armv7a-dev_1.3.3_armhf.deb Size: 250800 MD5sum: d5258ed2497d40431265e20ddfc5faf0 SHA1: 7a9e26139c49b3147b2b9e0fc30f71379932be65 SHA256: d794a62afcac5c4e6a46829f426106d1f5003525636fa551c62a6c6fd0815003 SHA512: 9ec1b3523d303182b5e438d4c08241310a98dca22a7efa1f616368aa94177623759ef013623b5de440e54b0d00c28fd09eeda04c792cf1f91ed232dfa9ba47d8 Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 364 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohpico-armv7a_1.3.3_armhf.deb Size: 149298 MD5sum: 61715e33c3e3e01d9802faee19345a92 SHA1: e17007ba7f077b5c6898a5c34e50110371db272a SHA256: 3abd58dd0276e5078f8965f62cd073e48c0e9415a70ca54c0efeeaafc3747a72 SHA512: 0af2a27e345ada9a926cae75e55d999aca543dc4701413dca07746c9f476ca038513e63ad5a278cb292ad83a7ac4cdaa5879269bf3a1d044d4b8c8dfa20277ca Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1511 Depends: libzenohpico (=1.3.3) Filename: ./1.3.3/libzenohpico-dev_1.3.3_amd64.deb Size: 300502 MD5sum: 6d2272784d1f009346934f4bc8bee0ca SHA1: 28052076ae8cc987933097e9fe2ac55a308510df SHA256: 4892a6584c52dab9ad956f5ab59ade38c4dcc3790d0427578c660781c188ee48 SHA512: a21d4080a3269ee62198984a956dbbc71270ef70320a939f2869388e5f99d0ca469edb9e05c9107787cf02111229be8792a7fe180ce014cdca0eea93740bed25 Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1257 Depends: libzenohpico (=1.3.3) Filename: ./1.3.3/libzenohpico-dev_1.3.3_arm.deb Size: 252052 MD5sum: 8fd2c4940d7f24145873a079d52f09e2 SHA1: ff9003895201f7b8992f19b02123084bbde27f9f SHA256: d2b2c03c14f5b26b6dda749b0e1669241a1f22ee083ff2a9bbe698b7a83764b5 SHA512: 79789e2baa74da63ae1d36e2076433a9f9b2e31461807dd599ff11284467aaf82ca5fee8a8ace98d18601564e91ea1d01209575d1e118e03a4be6c73d94f233c Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1522 Depends: libzenohpico (=1.3.3) Filename: ./1.3.3/libzenohpico-dev_1.3.3_arm64.deb Size: 296934 MD5sum: 6c81e3e19d578a2441a25ca64ba64d9c SHA1: a1afe4163758eed6ca165bc139e0b6dbc0c3bcaf SHA256: 2c12b9251ed749e684c3dec12a18cc7e0aa58cf800f501cfd58a7160f9c2196c SHA512: cfd3a7930206d90088ed32cab791a194c963bb9f8e075bd311ae95a00c6ea002728195be132ad2ae670968ff5e38c5dee785e5f768b9e922b5fab9d599f84db9 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1250 Depends: libzenohpico (=1.3.3) Filename: ./1.3.3/libzenohpico-dev_1.3.3_armhf.deb Size: 250500 MD5sum: 06be5df77a628e57ebeddd2d1de8efbb SHA1: 25fc69b9b54fb6a156f56726347cc38ff210de21 SHA256: ec56bd559db4128dbcef571bfbacf504b152a7b7384bfbc4efda27b41586a32c SHA512: 5ad0fc1c118fd6a4c13dee179d30699f5308ad3372583e06e2ed7338718fdaea09d08c5fd562bc8ad3c0a608522c1ea6970b2321e7f53ad920a63d001df2b0bd Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1482 Depends: libzenohpico (=1.3.3) Filename: ./1.3.3/libzenohpico-dev_1.3.3_i386.deb Size: 327690 MD5sum: 23de65044108904dd81aba81b94cb2f1 SHA1: d83730e0f09bfe15344d070d4044ddf308102a27 SHA256: e9f9b27eb42c7d4b6bfd9fc95664cc43439b774d631106546f81212ee54ba233 SHA512: 032b4238de6c8ba24fcf9642db2eed02e4ceacd5aab61ccd8a20610b5526cccb450de7f97c47a4f9aa917dae07815beb9ddc6082da77bfc86cc3fa646b853b9e Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1405 Depends: libzenohpico (=1.3.3) Filename: ./1.3.3/libzenohpico-dev_1.3.3_mips.deb Size: 285106 MD5sum: 80f0176e876cf8e9e45ba8bac1f4762e SHA1: b3b69d60b33eb5a75a7709a3c04eae2b8c1573b1 SHA256: 6a9a2ac99c3fa6adbd17cf9cb77e004efcd36d6329a27e7788466f09ed8f69f3 SHA512: d3b74c792d1f5cc6578f1ae7da054b3448c58bc2008d0c6adc6165241de6e0fe87ef5723652dda5bd3f9dbd9a14d273a3f4281ff3bf9a7526e728143ea6d021b Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 496 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohpico_1.3.3_amd64.deb Size: 183818 MD5sum: 7fa1f04be3d96609dcb32ed5d7f60353 SHA1: f5d47527e3c498f180542538a1a0e0f428e7a215 SHA256: 362e0019247a80111669d708f911e556aae77d3777bb8361e3807b70bc50c649 SHA512: abed4a0705263a5845adad9b779f37b50d5e3042aef8a3b5b7f9869adf45bd392f082616ebffb8a6ead17d1af83ffd6f12309e394e761f71f96972c7f6fde349 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 391 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohpico_1.3.3_arm.deb Size: 158266 MD5sum: 7b5398b28c1fd122e853825d39a3dc04 SHA1: 24c823aee8627c2dc46e5c6cd5dac876a2118c91 SHA256: b6e5cdcb4d59467b64fed2f81281d20ba35ff5588887aa51ac24e2dd428744de SHA512: b30839cd27a1b288fd373b16ca38816d94a3c98a6d5e5ba43c5f46d12b59ab92070c18eccc6d85648c34f358144e716d1fe21f431850c53dc50b2515246d1203 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 506 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohpico_1.3.3_arm64.deb Size: 179892 MD5sum: a88d5e679a905bc2ea9dc69396709220 SHA1: 8e0862315b403429a0e27fa516cd7428fcd6cf63 SHA256: d8fb2519b86c2e651715e1f2a06c330023873872399dcaa833f8e1e59d22bda1 SHA512: c89a32f77f7b6ec8de40eba29b21b088b85854cdb28eba7cc570cf520c5ffbb8c499e368c3ec4200408aceaee5e15ce548286c23e25ab5aacc766a2e24e407c6 Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 366 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohpico_1.3.3_armhf.deb Size: 150420 MD5sum: ca590f8cb20d3e1672cd1b7a5f66a469 SHA1: ab692688a34e7a5407271d031f22015cde6e5bb7 SHA256: 2066983c6fb4d5dd20ead3b8917853b0af4ce549b5114e18022361a951203d4c SHA512: db95e6f7b3226fd00d2d92addd4fdde0b8667727b20a4ecc93667349156dccc8c0fe0b0bb106dd38f4e2f234e644ef12a51333539474269da1d061d0be286014 Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 522 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohpico_1.3.3_i386.deb Size: 209794 MD5sum: bc6c4c1a95dfe4443d29221808a399b4 SHA1: de845ba5f2b5166840f4063114b0d85dcbd908ff SHA256: ddba1eee4f03a010c7a1784a192faf3f962e0e44a88d0c2590e6cf86b8da0b56 SHA512: ca1d01a5169debf413da12b4a2fcbfdaaa0fb651fa8712e34217a8d7d871502f8527a1a17d19eed90fb5ee52ab3029514a50c3b5b51911a6d043f432cdac7be2 Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.3.3 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 476 Depends: libc6 (>=2.12) Filename: ./1.3.3/libzenohpico_1.3.3_mips.deb Size: 164824 MD5sum: 2a7ecfee9fb8f8c32a6d00ba0ffcecae SHA1: 299f0996acb35909de1c17e5d8a554dcb3313596 SHA256: e72a5f2130ec98ba9568ba4f0180d9b02f21457835ce93695f73b3d295f9f047 SHA512: 44d3635250c6d2ca3e8c1bffb93ee5468e13c51f64c260177e76e26618e0fcf588ff0b9871cac887bbe53c26e57931124ee80a23adf90ab241b35cef2da129b6 Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15521 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-filesystem_1.3.3_amd64.deb Size: 3986452 MD5sum: b09fa76b44ece31149fdf1e96c25b707 SHA1: 18b17d41a02c0b1febe809550fd262a0d55348b5 SHA256: 94f834c7d9c428c445629bfeab8ef81c8cd976d56fbcd6559610dd5043ea5fba SHA512: a8f1de69eb4e2c96a4e71283aba40f02da689d93ed957e279daf3c2522c31c7de512795e232e1d742cc275bfa1098ce26286c05c5fccf78b5599e12688e3c8f0 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14117 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-filesystem_1.3.3_arm64.deb Size: 3442420 MD5sum: 666aa077f40852613ae7fd51c83931b4 SHA1: 8eaab1557d32f1a4289145ab17e2163e43209be6 SHA256: 4a94b3e943f3174a5a160e3e1b7016d0fa88d294a8a7a4d585a179b2be86daea SHA512: d04f52a87f149c6ca9268bf92fe8d114982d2072f7bbd5a1963691b7007bfb469359c523c191e369ffaf7be115bcaae1ceb962c008bff66d74c24ee53f461aa1 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13280 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-filesystem_1.3.3_armel.deb Size: 3390980 MD5sum: 3260b094de4be1c8c4b7c1f2ecdcc701 SHA1: b598355dd11309d8f4aa91531ce24d4acdbcf5c4 SHA256: d516cd2c8a8ff201288f6649a49bf6303890ed8af50d765697832431a292983c SHA512: 8b18b0dd2e8e4cf8c0847a89713773edafb89d08cb1b89ac45f30e655ee2dd209418dd3abab315aa76eba1353bb0ae656cd1bcd17b2159920f9a6f7f66b7c767 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11241 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-filesystem_1.3.3_armhf.deb Size: 3504132 MD5sum: 5e318de81fa9a743931ab2750ad6b93b SHA1: 4b6ebdaf615ccbd0a76f47c842369459f2cf5cdd SHA256: 0d265109de31012d093a624227f1b9c3996f83235332a1ab7c663f950e18f054 SHA512: d037d0f272eecf3ba0c468b7aca5cee7d160140fa37b72bb1ae788d0d854a3042b4c99bca6c2a7a3a1a283f909372ba2b7b2bb566fe9347b8f5cd364f3735aa5 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8057 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-influxdb-v1_1.3.3_amd64.deb Size: 2077768 MD5sum: 7ed8c3fe9743cb2b5b9ec55dd073a7c0 SHA1: 355c32db94924f2ad1e575acdffeacdc9fea6ed1 SHA256: b570a1d194d2bd538ac3ae99413e092b873fdcad5c2cb2f73d73fb361fd2f4ae SHA512: 952b9fdfdca9107f045daac392b11449cb86e62ad2a9a4ce6f57a79c0c4a50fd170186b4f38935c24be84c75215e09e05188b066e167bc109a16c1e73304faea 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8008 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-influxdb-v1_1.3.3_arm64.deb Size: 1897640 MD5sum: 44bd8c2050629e2c2bf9ddce492a1131 SHA1: 304f4fa477d4e5a774ccebe297bac6ab7e3fc234 SHA256: 0417c9b1514d73a9ff2d13b428a6c4ba8982a6ed80ecf9ee22c6628379520df8 SHA512: cb7321afe7e629a6dd50c1b45b869177245d8c8e54bfec18356a9e0619fdf953270ee49599e9f7a1aa9f5ce67e90de311e192d9ee9658666277ce17caa0ff422 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7121 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-influxdb-v1_1.3.3_armel.deb Size: 1730956 MD5sum: b9f38cae6ffe3c4a9df56c99cf064945 SHA1: fdab8ffa813ab952ef29841b25adc54b11941f46 SHA256: 8e5cc841b51a45aef3affeff83b0e1963d8d0ab7859a44bdfd3c0b3a02bc48a6 SHA512: ba76b7ed3c56c918e7ffe8b9cd51f0507cdd4aac8aa186f774e050b715976cf50afafc9404e5168b2d605a9c40bc9ad60bae3ca02db385adfe22cfd9dd041ead 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7018 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-influxdb-v1_1.3.3_armhf.deb Size: 1721968 MD5sum: d5862501153d016a73238159438b0850 SHA1: 00e5b6def418b1c24f4c7ec0620323b49e7e2001 SHA256: 6e9c04744d2d8f700f7a6206c2b6a0f06d06459e8884fa765b0cbad1501cb2bb SHA512: 97766b78edf286e7cdd0afb2705fdc50cac997ec7dc5a6e160e6882afc42154bdfe2e1588ba833da87933772a005d867e83637beb4c90e41c98ac189221d536d 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10763 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-influxdb-v2_1.3.3_amd64.deb Size: 2794048 MD5sum: 64949af13c471fa08c5ba3c364938aa6 SHA1: 9a59a7f782b9b8454f9415a23c002fb15c8bd137 SHA256: c96f0feea1d92ab50666062a6b9a60cef4bc954630e1b22947fdb3c4ca19f7c6 SHA512: b8f88fe40a5eb38d8e6b49097952d602694235efe53396b75afff31e963ea1fb9ca138aa7682b23c0b41641be7fb6dad8e6ebcb44a6a3cfefc7fc5d636d12df0 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10725 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-influxdb-v2_1.3.3_arm64.deb Size: 2599512 MD5sum: 3cf11ac12a52f1a5b2c77722084733ec SHA1: 164f26311e39bcd85e8f6fd67f4cf969a6190ec4 SHA256: 9ab15e841aa212502032b9eda4e2d182595633b8a1693db197e2885f8edfd02b SHA512: 70350068226a858193379c27734638e98c1ab2f420a13d1b0694f21c742c34505d3a5efb14fa5cae7dbc83bc3dc604a1984e7f195118375b7850bc0df7f26f1d 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9665 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-influxdb-v2_1.3.3_armel.deb Size: 2399368 MD5sum: 470c1de4864b5264199ef05067438bf5 SHA1: 620d015d53a2c2392f00173edfb74671634e617e SHA256: 15f922c11daa1ccf227758ee67cdc2f152ac4c5b3f7330b4d4536c905f1b8a73 SHA512: c9b11392cd6a3aad0b308374a1363e6b161358a518a93167f896c8b4a4bff7323080b6757bcce97bd184aac9b1b5e2e8087107e908585236cb0c8ec15d7295bf 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9523 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-influxdb-v2_1.3.3_armhf.deb Size: 2416548 MD5sum: f8a338174211bc1a62fa0b62cc27bc22 SHA1: 14416821425779780470e17120c8197c43c215d5 SHA256: bc390aea395d9aa5c14841b6d182db20a47c0992d8f9d57f0f819eb87ac954ab SHA512: 7c768f9ab223472c1d78eeaebd034fd3a7ba27090e73f9cae8412ae781ed40828bfcce5223635a03d038a6ce773a64d96f93f23131a72b09ec53588073797d28 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14472 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-rocksdb_1.3.3_amd64.deb Size: 3766876 MD5sum: 03016c9f4b66eab42d2f194b96be18f9 SHA1: 536650f2fefb5eada3cf606078bb9593f764d99f SHA256: 8cb43cf0ef5cdfa88f8ec3a7f67484f485aea163495252f285dc87575650f61c SHA512: a7eaf136ffa05d8f1a5bda30a43a91dc29923ae66c7c489210f34006b05b357651b14af62b9baa441877aa758c9da4140b7340a8383f87ba45ca91a8ef7731ed 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13053 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-rocksdb_1.3.3_arm64.deb Size: 3247932 MD5sum: f6c9fef6d604cd23756b2a770fabe052 SHA1: 4650d2004102d43ea77a678931baa1b20d3f9444 SHA256: 0d24a55703f938a64691d0dbb9bec56d6fa3f4fb4c05673364cb22cd085e99e9 SHA512: a69e60e6fba71277b25ba342e734e972590aeb945127ee9a74f78f3dde7620a91515cc38a3c3401fcc7ecbb1f39e7fca702f27a30d3c9465579e91f8402ef970 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12432 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-rocksdb_1.3.3_armel.deb Size: 3216092 MD5sum: b46cbf040509e907e3ca65baa5a586bb SHA1: 3be03a70d834b17e5fb3930bb6249e64c2a44a80 SHA256: d4e6d9ea1784916793cbcbdd9f2d30be05edca6544320480c4b6ea5a773adf46 SHA512: 254d7fbd7dd5208214a8ae7473746feb199ba33155b2f530c22eb65af11162702109a5f3ef8aaaf9598228fbe7d3f9b1d1979c1736cf6a8991a1af139f3d7502 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10357 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-rocksdb_1.3.3_armhf.deb Size: 3340712 MD5sum: 784c719e589b81d95c8f0ef0b9aea35c SHA1: b37e2ebf06d20116a3e4d339805d050221681282 SHA256: 645df6f792a7d23cd4b53e2dbfa8a4654ba593ce6a70e29139c1cee13c4f3951 SHA512: 67660dbfbc2af0a90732250ffcc34ca9f3519ebc5e7d356c9d6cdbc42b36fa08b6d11ed3be35b225501b4ee1f0bf4c2d89c41c02942f71a17851a5d8f29a33eb 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20342 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-s3_1.3.3_amd64.deb Size: 4425868 MD5sum: 98caa0b86dc3a883ed5e56db9b6db1a7 SHA1: d6492060304a7412cf9df5efc007fa07f95a35a3 SHA256: 6c6980ba3af594db4ebf86633c6c598d573986bce285f70c8b809485041527af SHA512: bbb055a6618c5a8e68b5084ff18569ee0dc3705366f023512406fa8fe6f0b2937cd8fe3a7a15616430d31d2d4147bcd4e737eb2bd8b86c6d15071762b10c1129 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20539 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-s3_1.3.3_arm64.deb Size: 4202220 MD5sum: ff016846b81b6e23befdc79af1ecd392 SHA1: 6afb32ef3e2bb97732b32f75eb1b259c0a6064bb SHA256: c14226f6137fd509eef3dee93134f6c38ee290fc071d1715c874da92f65dd6ff SHA512: 2ba2469b7cafb6dbe8d062cfc48bb4ea83878e99e6b632e2bce682eefe74c1babfcb941f570dc1cce0611557fd7895e8196cbed4ee59fee99aec670f1401cfbf 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18964 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-s3_1.3.3_armel.deb Size: 3902496 MD5sum: 4058a2b0d557b5a0dbc8426c9d6d21da SHA1: 9277d8d1889357e5efa262192517ab97856c4f21 SHA256: f7f6f5e02e7fda3ed9340b7c75a198c4c31e5859602cb56f9719397c790bda24 SHA512: ffb4c46dcf8d040f87aed55d961932e1b014ca326086f7186c70bf37ad1759bd09c735442fb3d653d5d14eb40e6c0e0fb5780a6bf7e6d2b8996e07c94471ea0e 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18712 Depends: zenoh-plugin-storage-manager (=1.3.3) Filename: ./1.3.3/zenoh-backend-s3_1.3.3_armhf.deb Size: 3944780 MD5sum: 4fbe462d4f8b6ed8dbc71139d1a79356 SHA1: 68a68b0f48d4d4e740f4c6d20d435c90b57ef6a9 SHA256: a10926fa82edcbf52f49c5c1fc43a796ea86f8669746f974ddc397a9a9ad1b62 SHA512: 932cfd5970378744c296ff336b3a8159abfc49e1c10bf776074d6e8d46f01510016d7d3484751100bd13d55b06b195904beeae0fab1850bb67bb08b727adeab4 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-bridge-dds Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16029 Depends: libc6 (>= 2.38) Filename: ./1.3.3/zenoh-bridge-dds_1.3.3_amd64.deb Size: 4637200 MD5sum: b72556787303cf56ad14dc0dca344501 SHA1: e074d6ea9675a074f97eb454503c80ce8bab1590 SHA256: 373837d109d265cd2c5aba5d7ef8511ed05f350a6d8e63ed71ecc1fdf0e1d25b SHA512: e7ba17b9002f9d920ea8154c4d5c9835112bacb0255dfb17d1a2f816da1c5a7055ef4327218e77f467e4a59531290ff31e4cd56aa4c6f0d11c6653a523056595 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14791 Depends: Filename: ./1.3.3/zenoh-bridge-dds_1.3.3_arm64.deb Size: 4145604 MD5sum: 172ef8dd2beff14f93b2c168ed8b8c83 SHA1: bff6058e7a44df1e55c92aa467aa2ad851528ba3 SHA256: 32053f934f4e99a76b9e7822c10b435c3fc7e2a0d06c236d42c298906d9a0052 SHA512: 5d54070d97bf6e7e344937dfc2bd5589eb02c9ef788138a08ef96fea2fbef65d71976f68b90da1d80ab16f9e23891315c552537a8f3088cfd473f7e913554dc2 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15175 Depends: Filename: ./1.3.3/zenoh-bridge-dds_1.3.3_armel.deb Size: 4234828 MD5sum: 4153c9c70316d88a0604b7cf8d9a0b3f SHA1: 47853e28e364eb284597384590b68984727e1d07 SHA256: 235edf77cf7c276312f6fee3b0a8d74ba67a428fe59ba47dc9008348b31e3e24 SHA512: 7b21a5db0bd8709c89477f322e45730d627dcc7079eb73bd9c5e9141fd2ef3a3dd46e703ee584baec9c25d8422d79fb42f6376e70af9635026a3ab05e46cabc3 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14631 Depends: Filename: ./1.3.3/zenoh-bridge-dds_1.3.3_armhf.deb Size: 4251224 MD5sum: 408c5d08147b9b3a713b6888927aa072 SHA1: 2797564cfe4aeee71895d6a50de94a0e8ea2424c SHA256: c5bfba5a7327de31362072daadeb813aa59ce34a82b8e660d7b7e115c76ea386 SHA512: d7f3eb74c780a2e20bae7236f29bfc0b6b0a5697dd64bedf45326746540cc6b3c9d7e2d16d990b7aa955108db71404ae5b63d09ed70e2999fadabd8d65ca50f7 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-mqtt Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15984 Depends: libc6 (>= 2.34) Filename: ./1.3.3/zenoh-bridge-mqtt_1.3.3_amd64.deb Size: 4331168 MD5sum: bbd8485db692f09ef1463d37d4f3ccd0 SHA1: c907dcd1ff4d3ba571aad3556489357f1a361642 SHA256: e3c6b307492bad283fc242dae11af704507b2f6ebbd230590c97df3ac17a49ee SHA512: 6290c498bc8c2e075fc95a81732201c163bf09e3a2ccf3149182d09a9f8b5bad94458d7bb824333a1d3bc277b75af91a5ca3540323fb03e2b7f4b55031023a29 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14682 Depends: Filename: ./1.3.3/zenoh-bridge-mqtt_1.3.3_arm64.deb Size: 3852008 MD5sum: bf7475a948036a299a6cead05941f805 SHA1: 23cc44212fff7193dfdc90b555d09baa44bb51f2 SHA256: 09922d315cb5694de68cf6dca1946779365face206c5d926dcdaef461f67eea1 SHA512: bbaf924daed48b99cdeeb15f211e65db4ee646fecb722a7ce2ba2c9b6140b8f441f6c5f673f1bdef0601c528faec4d1b52f26b3c83c7342f2685cb8a3233b5c5 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15288 Depends: Filename: ./1.3.3/zenoh-bridge-mqtt_1.3.3_armel.deb Size: 3970844 MD5sum: 4675138a2123fb15f91c26b8d5b4a6d1 SHA1: af34848ba0aa77f792ad94496fec0ee4583908d5 SHA256: d44b7b42abdda45a210e721f3bc77197ffda7efa6967c17ee7604c46a9720e8a SHA512: aa65d2b83e8c33714cc9b4c721be20d8e138cd1431fee84284985b3a53028d8bb5909ec779be696add4d7a6d824989558bb98384d394a723ba85eddf61301563 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14964 Depends: Filename: ./1.3.3/zenoh-bridge-mqtt_1.3.3_armhf.deb Size: 3962796 MD5sum: 4384d2b4ba39ca6ed5259226e946483e SHA1: 66de826464ac54e94c72755c7ca4495bcf7d5910 SHA256: 2222edc3d5aa6e5608f8f16dca0253481f82d4fee15e88c477f240bcd01f171a SHA512: 1ff2f2b4694544b0067f0282304396ea78ebd4950dd3f187fdb9c352931c13d2a5a6629ee320eebd86e2ce0e5ef146e1e409eff6584431201b4f27c37d79b69f Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16659 Depends: libc6 (>= 2.34) Filename: ./1.3.3/zenoh-bridge-ros2dds_1.3.3_amd64.deb Size: 4758276 MD5sum: b5b127dca06112730f49865ab0057a26 SHA1: 4540d7145d2390eea113c2c1f5b6b5b748afaca4 SHA256: 0ca4cf9984b51e361b994f8064c6bb6df48d12230988938ac99d6dedb9daa71b SHA512: b879d9c32f1df49827a4cfe17a75cf064fac37a916af1f13ab81ae63351c6c888112cf177ff9f620f9039c484827f76918e9d6bada90884f695855cf7725fee8 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15345 Depends: Filename: ./1.3.3/zenoh-bridge-ros2dds_1.3.3_arm64.deb Size: 4256432 MD5sum: 43ffbf465a50080e291b1c9a785cf56f SHA1: 87801c70c00f597377f1db96760f55e84028c798 SHA256: 83d92cf780bb8399188ac2ef32e1abc975945420077ed67cd0f890af81a311c1 SHA512: 5beec9b66f635e484a61aa546862fad5167e5fe51ec41d30d01a3d7645fda5f31478ca7914b33a7583740c33ef2508bc2a4f4d7b8fc0345ee052250a226fdd3a Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15722 Depends: Filename: ./1.3.3/zenoh-bridge-ros2dds_1.3.3_armel.deb Size: 4353292 MD5sum: d41232dd19c351aa1b74d5e1818ebbcb SHA1: cb28a909fd04cdc00477603b6bd9f99d91146e73 SHA256: 7c8c94eb5646be64d59d7a7af88018644c84fad42247be9326dd3cad15a96d27 SHA512: a9cb7b4d26d67dd789b8c3a51ce6257b63f72ce49bf31555b7fc318806b762ccacc9d334384ba26d5e22826aee02610ee6f83cd70eb8bf0b33281e3ac809be69 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15178 Depends: Filename: ./1.3.3/zenoh-bridge-ros2dds_1.3.3_armhf.deb Size: 4371244 MD5sum: f113ef41dd8c6d1de9e614fbbbbc8872 SHA1: 5452dcc3b1d492d8a965e6fb4b2733025f591cc9 SHA256: 3ec984a7c3de711e21924c1a280f29e337b05f2583a9cdb42e189cd5370fc7ac SHA512: f3dc34d5fbdfe118c396ea97f304218c0ca0ab170e4b7ec6a4db63561bd2fd0707191e42c090003efcb73d29a4c1443af9fd58a9c910b10639768ef98116ce4c Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-plugin-dds Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6316 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-dds_1.3.3_amd64.deb Size: 1704788 MD5sum: b8f1f84a52345398445a2696434fab46 SHA1: 8563731dfd81a337ac700df9dab564a7721dd1dc SHA256: 055f2d42de7dbdacbb53bd6c35647e71f716318e61492c94f7fe1490d2295f8a SHA512: c8a043efebecc27a0a9e09ecf4f653b0fae1339a5c747dae1b04e73b061d0ba86a9558549007d9dd6cae8112c335decfd39d54ee0848050daa78d104617f83c0 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6244 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-dds_1.3.3_arm64.deb Size: 1554724 MD5sum: 96751759093b9a0a4e46fc4495bd9567 SHA1: 18b72c1bd2f31d1a09e07b59b645fe9bf7ebb3a6 SHA256: 308e94e1714f8652ecdaa587395280b0f1b809b8151f2197a23fa022ade2476e SHA512: e5170157d62c0b624550800229c66e70fd3601e3446efca32afcf991b0c559ac8120d99600b559af7f7d58a444a5d13195ccd9051f6353109b8df765f3abfa42 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5820 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-dds_1.3.3_armel.deb Size: 1560028 MD5sum: 220c4b1a59d1803fa0f226448ebf428c SHA1: 48214bfc9d6a17024b6a4d5e9a4b1330c3640045 SHA256: 6a4f5b43bdac1db69193602b57944217bbf9b4bd028f3f7d3259af2fbad28a66 SHA512: 2358ac8c4e0672bd62e5c4f36aa1fcd8017eef3ca9aa70f8705e722471c6e8b8142c5478dc2fa03ccd92c5c2c45138e3e759aa8f4a175ab5b1740ae129b857c2 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5478 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-dds_1.3.3_armhf.deb Size: 1576780 MD5sum: c9ff45e7d4d828737df356401f836cfc SHA1: e79479918b47e603e1cfce44ab4212b58a002fee SHA256: bd90e467d0385b430fc342ea0f200faf8c9bbebc4c70c7089a4b3180858a37f8 SHA512: e5988eebc10920a334b721e8b49131e78b2e55e9245c0a4a4d5126cadddc653e0eeb3570face338ea220d5b53f6a81e9041ca16c26b68c9641f8f9f6a52199d3 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-mqtt Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7700 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-mqtt_1.3.3_amd64.deb Size: 1926784 MD5sum: 080b01504e9bcdaa75b8a64635b2853c SHA1: 047cae704e1e4561c8a068bffcb650d994f02dee SHA256: 60c26d2f2a41cba8d6deac04942b1ef2911c2f30fe76d2356a8c8ee4e6250bc9 SHA512: 88c386faf3f0155f9109f61ca0c9970a8a7460e7fa5d6417a7c9f2f54bc3c8c7a5137dac4e49ebe0ce9fcf73693e64e42a34266dda479811c8f74a8cf3f124f5 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7451 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-mqtt_1.3.3_arm64.deb Size: 1750896 MD5sum: f5ac72fc5773e9178441968e0177da60 SHA1: 26f32bf61b49ef54353e96f55c563b382b435be7 SHA256: 7c598f793ce265af5fced22cb4b014fe35328381341468702fdd227a5a1105f4 SHA512: db6cc3e81859791e9c0d0d73b8741530032cf70ac289d7db8b0f25c20a452430a168eee52af437a870f75e27376f063e26b273869bfbbcafaeeeb4c73e6c68c2 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7046 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-mqtt_1.3.3_armel.deb Size: 1632576 MD5sum: 499ea93970c071e885c180923c1d3f8c SHA1: 82012a417990924c56d783f107ebeabfefa8e3d6 SHA256: 461880a7b27bfcd5826efa080160e86960ab9be06fd0fcb8cae19f3fe7caa71a SHA512: a381b2e10349b34715b37b9403d10e324acabd81ac4b9a1205be8e1c4f704eab0b827a1ec83e949e55998830bda53dca2807db4b8e6b6786f3d62816cfaaada4 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6884 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-mqtt_1.3.3_armhf.deb Size: 1637932 MD5sum: 3aeba35597b5aec6228f33b5f5ef4b88 SHA1: 1a86ac3479d5cc873bf90a40da43a844172bff39 SHA256: ec07581d2ca75461b737280859b8d310d277c79bed352412da854ee22e258e88 SHA512: 540ee106d71b16af24d6aaf09855c4444dafca38687c0ec49576e59b12170ca3e65e64821c40385842dfbf7c81958908f09d882c7debdbf929acaed9237b8816 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: . ```raw 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/](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](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. Package: zenoh-plugin-remote-api Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9802 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-remote-api_1.3.3_amd64.deb Size: 2464928 MD5sum: 97c32ba3368163775ee27e5afd7510ca SHA1: aa3fe7976fe08156e630b5c5bdacd30c2380125c SHA256: 7c44d026fb4c32d0ba98c03c79f16093d1757504ed9f3ddcd06b9978fcd942be SHA512: daa6b63fa5fb2e58c2387a2ba5af53491ded1177d4ad9b2c17231d1a68659a9ca53a4bce9adb0f2bb54cc0d2bdee0ca9f3bc958b8c244bb1232b9b6f2b7a0d1b Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9834 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-remote-api_1.3.3_arm64.deb Size: 2287004 MD5sum: b772581d428b01b8a06751d084e1cdca SHA1: 6be820755d458efa8f541a6c401861b62d8f0307 SHA256: 9b732ca76717dfb60083b6f20b06269f656507219530074dfd554ca5193d8598 SHA512: bab3a9985943bed13a08c7dc88b2678b57d3b20f3e7f861013983fb86f11b037d4b83cf240531c645a144b60ec17180707f4307bb88ac603d1b0d3eff7798cc7 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8810 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-remote-api_1.3.3_armel.deb Size: 2059116 MD5sum: c118385807a02ed67157478252674c5c SHA1: 06bf90b80fccb2638ea0b673643b94fb2fa98c99 SHA256: de4a8fd37e9d820b51b317e25f0f16be0f32d1950ea551d24f2b65ac26d0c7b8 SHA512: dc531765b8627f09a0c9b1d0ab3a3983db242f8627bde7e635d85d70a4abb12cf515f45847b2015db3a24ef5eff988af77f8109188d86fe9006713ace633bcb4 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8643 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-remote-api_1.3.3_armhf.deb Size: 2067600 MD5sum: 51f77ce9c7f2477cd3aa0b5749ad4833 SHA1: 63379f04c22d08a0f8a28d6bd52866732e762232 SHA256: 5fd4687b2ef4a2055345372f5ab1d8389f831484f3c5750e5c36de1aa00842b7 SHA512: d0f78b4179f7483181e5f2911d3094deb2c7368dbc3d938fbc65a5a82c805c504525d751d82291453d0e6d88b0013b8174e0bd64f433dad2568e6966eedc8f84 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-rest Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4598 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-rest_1.3.3_amd64.deb Size: 1238272 MD5sum: 0d02e6246df2e56cadfada99bb208353 SHA1: 1f809e22a859687c2d897343145cf894b6c19493 SHA256: d4581d0d9001dde8572bdf8795ef9f29e592cee9875925331bfa11ee702df161 SHA512: cd814f4584e5670f271005948edc5e077a52733fa66192315bf75af972545e76b88dcc8f3349128db596f7b29b3363de19d4ee287fe09bdbb77e1201f1beab34 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4631 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-rest_1.3.3_arm64.deb Size: 1144532 MD5sum: c8804ec32fc167c8d01c68ab086363a8 SHA1: c38c5c050ad0840690fffb893479579f7e1aed00 SHA256: af75ac439dac6bea1badcc7963765801fd36ef4c9fe8fbaeb8a2a3c89d8b1f9a SHA512: a33601bc472ddb57feda1ee76e62e9bc8423296c5380f640091b35b1ba2e57473255b299ce390bf7de7bba0b2d67a004f99ff3127dcac786fbc4c866392bf7c5 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4373 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-rest_1.3.3_armel.deb Size: 1181284 MD5sum: 08648a9b05f2c4e9edfc73a318dc7e4e SHA1: 50e2066422fa7a055ef044e2a875806f9dc7632a SHA256: 8b51ace45d316a17ba7267956bc3359323c21c54a0973ac941a941c221d06c38 SHA512: ee3aae3a1d07dcd4e1b2b6795f96513184843136d2478123929799251ee1b533e2fd44c64815e5fd7cb110ed9fd704aabd8540856a788ff975a9746863118f70 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4300 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-rest_1.3.3_armhf.deb Size: 1177236 MD5sum: 867c598fe38c942cdb4dc594dc078782 SHA1: cee8bfdd5905d375efc074a034cacf070003cc76 SHA256: 088579bb0a7a7f992b4c7d8edce323537f751fa46de67a11d52bd1bed59fb092 SHA512: bcd3eeb768600184595e5111cf30e6af6a51d961ce4290f944d1246ed84b0d4e2d0c25ccccec6b8e4f0ee81f3e2b9d8b64124d87e9e9e0ecc5af37b0a6c30d7a Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6880 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-ros2dds_1.3.3_amd64.deb Size: 1809324 MD5sum: 07626242e2b8d88bf7adb1efb4fa2f37 SHA1: c439c6e8e0e63f0a7f288f0be4bed1d1fb391a48 SHA256: de69f79cf1a9e0b9417136b5b13eb1174b998143efbe4fa3796d640559f94e0d SHA512: 0a4f0303e4bf10234e8d5385eea19eeb7eb6f1c9caa598789f57c634d915a4107f3a16079446d61159047a83f8a142d9faeac8f7e921b2a8f9b3b43a0ad53c3f 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6750 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-ros2dds_1.3.3_arm64.deb Size: 1647948 MD5sum: 982aca386e8421dedc17abb06a5ce27f SHA1: 726bad23f65344873d529f8ddc5d1ed49eca5c90 SHA256: 18544f7231352e40cd1b43f96c3d22e43bc4a184ba141f1535ddff9f5083dc60 SHA512: ca03bab1fc76a134375821dc7209dc61966abf7de574cba9f1a9b840407d7863e6a660bea0e054da9e6834265f91ce0bb2ed7b23df34e5432153722e2cbe3a61 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6327 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-ros2dds_1.3.3_armel.deb Size: 1666612 MD5sum: f5f48441e2a067e33f0ef5ec1fa26988 SHA1: 54ec9710a80326bbe9c17982defd4dd871ef4abc SHA256: 182a0146664b5f2a09e6985cb37231d0e4e34c305af11fda1f92b8d27768538d SHA512: 08ce6d8f85f21d2ed529116f9d3ecb8a57edc3700c73bbff81c069897ece5ddf56afd9f9ea6641498d954ef0005199ec155b0f9cab27db5d58553724a7c721d0 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5992 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-ros2dds_1.3.3_armhf.deb Size: 1687484 MD5sum: 6ae72a0cb68b3f5c2f6cdde62934cfae SHA1: 57b8dd36c93688fefcfe7f093ebb3abc6876965e SHA256: 792ae23a018beed9ec3c409a209296e79c4502f7bf39cebef2c290c9eaa8b4f4 SHA512: 1cec31214216597caf9c9ce069b1a1d736b436813f488c0a25a3f56f0c174a29f26ca0004962c379070b2ab21f3f779a1c623c25b784051827ef8e7848a7d486 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4336 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-storage-manager_1.3.3_amd64.deb Size: 1129948 MD5sum: 81781cc267fb2d03c652011b9e65d562 SHA1: 491aa0665cdf03db4f35b65fcbce67276f864bf8 SHA256: 34b263b01a1ccd7284cf29ad6e918c53a8a5c1d62a5eeba72327c4b077082b94 SHA512: 7bb96699580e06cbcc37ee8109b481d5647d7411e4d21a08a25e96c8c3312a9988b727b7c6ae868830a1bc07c55cb2a63082d0301595eed527aba99c40acdfba Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4352 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-storage-manager_1.3.3_arm64.deb Size: 1047152 MD5sum: 17599db47df1b86b1791a3780b142170 SHA1: c6d42aafe57f536ac782a3d5a9ba3e214055b170 SHA256: 46583cb894e183cc22c4f9b66fd8c23bd741817b2687ee3c388ff13d4ce842ef SHA512: 1360b8d9c389b6487e652b61d79bd2adf5739900cbfec96b5fc985d26c12e055c21d408971d5c55835e669a32046083ffb513285eb0c8b3f11d7388d177fda89 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4118 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-storage-manager_1.3.3_armel.deb Size: 1095324 MD5sum: 68494fcacd4141e678f9ea10444191ba SHA1: 0396e43c68670454abfdee2aed53e43a99b65530 SHA256: c063f7d37966ac7e2ac4e3b998643caded75005e03d1f8fa0c833f06fcc2ab3e SHA512: ff89442bf8ab8b613e7264759d6d2e948bfbf04d4ea4c4256ccb2150667d8d59c98f3496cb03017dda4d19597944c099adc4bb2b32a59295ded013b17ad711be Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4030 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-storage-manager_1.3.3_armhf.deb Size: 1089820 MD5sum: 1d1bc8792e158c5b99620284d4dc411d SHA1: 72b8a817f3bdebcd54c0347d4fae8a436b928e70 SHA256: bc9510e31e9d7a413392c97162bef771054d0ce41f15384117fea0f476e0fb65 SHA512: 1447e16732294b7740ab248fcc50b7ce69ab3f730851cfc261b9b7866a9e6582c14951833a0983ab2ef10f2f30db82d3ffcd81d52c10fcd61eb040b7d0a2af00 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-webserver Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6963 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-webserver_1.3.3_amd64.deb Size: 1653684 MD5sum: 760645273905c38777d0b98310695d6c SHA1: 7684ac31d03310f45bc1753f8c8bfb697e961981 SHA256: 90ecb42bc8d0003451095b1e1ae28c2262821820ace5057dd0524fb3b1ab0b21 SHA512: 17cd477f7a878d97e3855d685b7100252e8b6a1dcd7b39dafccc47a342a81e22cf75acf99df6c42a352b9973cc26c135c90a49b2fe48ff87d51dc25ab28b5df0 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7180 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-webserver_1.3.3_arm64.deb Size: 1551060 MD5sum: 33e6039036c92e19f03dc3b248bcdd32 SHA1: f8981fdbd2a39900904afaf483bf240344fec772 SHA256: 3c44741e66e0872b137b980f15b4cd5fc64add0246890cc743f7591c38f7f495 SHA512: 6bbcb1b687377ce96449db241706d5cd59cde360a9a98c1f679db7040fd04a3e26292cf85c1ff78b9379ff396088851d7d18386193a0246321d2b652f9908114 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6488 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-webserver_1.3.3_armel.deb Size: 1525088 MD5sum: 5ec624adb45e5e26e5f73100dfc73c8b SHA1: 047a18fbb1473b1aec3d3a4a5a6f205d5bd352fe SHA256: 459b6ef73f3e92a6ea394bad0b3c7cf1fc90c0910a596e5b0d5facefcdc5e0ce SHA512: a3b3892bdc9b6d3000b3392edee496fd41e40d83d8b4272752efcc8a8a7be0a08e15af466ed2cd4f304ba02f20aad2a99b1c817afb4476384a8134116818a72f 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6383 Depends: zenohd (=1.3.3) Filename: ./1.3.3/zenoh-plugin-webserver_1.3.3_armhf.deb Size: 1518544 MD5sum: 3d6a1a5d996e4a1d46c565c66a7f5d49 SHA1: 0dd4cd90c7c914d9d5ca05c8fff80e0cba829866 SHA256: fe71e902bd7c4178609b3e42264b66f83a19d968dea1fd614632da9b81816980 SHA512: 929b8f020ae4dd8f6172c8ae9907cf7d8f3c1c9c96b6f2f1dcc0d4db9b329fc3bea7c891a4bddb5bfc8635b76a5c201d3ffba3be2baf5b344a1b3e1e8df79f0c 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.3), zenoh-plugin-storage-manager (=1.3.3), zenohd (=1.3.3) Filename: ./1.3.3/zenoh_1.3.3_amd64.deb Size: 17552 MD5sum: 4ae9c56f130cef5d177d8f69ae8800fb SHA1: 8c63d2c2659d9bf176877a9c826a515957604495 SHA256: d26d27bb869b1a56fc38f0cffeee4549e0b32da68b131227f9850b9da2de926f SHA512: c84e56bd14c18a9dec53c91ad2a5c735e4353c3be6cdd8d2513539dbbd57d863d590ed5565f02c4d027a9632b32c888096d14bac29a078dd94f2dcddcc6c1a2d Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.3), zenoh-plugin-storage-manager (=1.3.3), zenohd (=1.3.3) Filename: ./1.3.3/zenoh_1.3.3_arm64.deb Size: 17552 MD5sum: 290d08a0571ec4807c013e74ec2f2229 SHA1: 3a8b57a3153dc1aea5b8d1f6350e73d8aef905b1 SHA256: dfdb48f18d62543694c3dcad384820b1f8e15bda8e2292206d88174b032fa313 SHA512: 86b5b7c82e745b0664a6f438e6428c77d4354cf705fb8e164d90aa2ba4c3a578a578c020250f8879c65ab6e57f52336320de00e0e815f0e150713f58cfdc52ef Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.3), zenoh-plugin-storage-manager (=1.3.3), zenohd (=1.3.3) Filename: ./1.3.3/zenoh_1.3.3_armel.deb Size: 17552 MD5sum: 91b4b52dbd2e20cee46edaf411215388 SHA1: d76df7af39f0c1f9762708c39e4771f49b4f4399 SHA256: 14616672e4e3780b50f70ecf022a296a4df2ce3099e78289b0a1230dc726b03b SHA512: f5252e86299f062685a605ea06be8e50a0d6390da32b4115defc4c57e2448e9907aaa569a9cbd1dd5598870bf77c653380aaa015f9a11a3455c6e1ea95cdc282 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.3), zenoh-plugin-storage-manager (=1.3.3), zenohd (=1.3.3) Filename: ./1.3.3/zenoh_1.3.3_armhf.deb Size: 17548 MD5sum: 2e07b30b4941a7434aae4c481d46161d SHA1: 03450c6eb2d554003aab5dad6048a98606994e6e SHA256: 1d5acc39653bb5d626cc7f3b27242d88ab8b8b975c7203e8ca95d299683b9c04 SHA512: de15f2e4ae483b3c7c40901946074d0a36c44802484d273140a9e4429ea8e8da983d18b8fccd441f87282324f82594fb6770155e749e317d3efa719eac87702f Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: amd64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13804 Depends: libc6 (>= 2.34) Filename: ./1.3.3/zenohd_1.3.3_amd64.deb Size: 3832288 MD5sum: 4d5b6b5b7a4ba518df46f250a3f2b01d SHA1: d7d2cee49a77e66279596d9970ac1ddb77528bd5 SHA256: 517f6e4a08fff4b11d9f54fa34ddb9f3ffed19e249016789420b66bcafabe6ee SHA512: 1d297767fd86e86830be85cc70bc0158781e94954b611fe697bdcdf1f6c51a5f894cba278c603a6d8ba24d9c82e32c0a8a07e7f00450a3604af28c4b59157476 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: arm64 Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12465 Depends: Filename: ./1.3.3/zenohd_1.3.3_arm64.deb Size: 3420544 MD5sum: 06456b0206f81e53a421e24963bc215b SHA1: 40d98f7a9456b76e04d7702fa26f8d7c380258d1 SHA256: 7de4f4cf0aec4590e7a95d1d21c20844b9655e0334a9375663180b5cd323df0e SHA512: 01b19cdd365926cda05fd15872d70ff8e420f84437d620f630ba86ee00137b16b622a97f2e544deff17eedcb8170afaae962b35704dcdd2f8a48db776d9082b4 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armel Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13113 Depends: Filename: ./1.3.3/zenohd_1.3.3_armel.deb Size: 3583476 MD5sum: 6baa64b1c09b95d4658fccee1ceddb2a SHA1: bb9b71cbcc510eda23cfa37c00cf31d2c3beef48 SHA256: c7d66b1c83d94df519718834c9f5ce633df3fb76f1e5b283829d6566a9442564 SHA512: 1d0adbba62fbe5dd1b2e6791dfc6d831384af96c2386424ec3f2e6f20a6a7e747bf500503d9f159b87716afa2e3fba89427d456a497515f1aae86b0c61ef1060 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armhf Version: 1.3.3 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12840 Depends: Filename: ./1.3.3/zenohd_1.3.3_armhf.deb Size: 3601776 MD5sum: 32a372d16934c4c67a796a411c184f76 SHA1: 772646f2c5349734881a2928ce210d7afc72872d SHA256: d78536d3395771e494ec03da49c0f6b6ca4377312d271b8a93adf311b268ec9d SHA512: 3b16acc509fd7a9263ed4c468f5b6481659d649623810d135a478ef90efa2a474ddd2151a550d36e43b653bd4acdc4d3510b017886a636375584cf9505306b55 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: libzenohc-armv7-dev Architecture: armhf Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30829 Depends: libzenohc-armv7 (=1.3.4) Filename: ./1.3.4/libzenohc-armv7-dev_1.3.4_armhf.deb Size: 9580916 MD5sum: b4e78497a59ed84cdbcdb7b6d425539f SHA1: 09c33fe561ea5c71710ab4cfb217e8bbc2d8d23a SHA256: 169d1ffad0390ef52db6ed6aaaf0fdb8c1d6e9654704aec754e0318278dfb831 SHA512: cd3d5045833273abc68b5fea7ebb4cf345cdd94b60862f0b95cb2c5a3ffc78e8298e04cbc07dabaaafa3a15c37cffaf934f497b188251130265314c317a906bd Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13541 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohc-armv7_1.3.4_armhf.deb Size: 5715366 MD5sum: 1cd433c49363eeef40eb58eb852bc699 SHA1: 2bfa83fa728a696c64957d9a7a5d2c87ddcf3997 SHA256: 2b46674dae929a75c7fc00175a240a180bb9f5e052870cc7ffc59f24cae567af SHA512: d848e0ab11a3ecf0a558d13300816e5c4cc91c326d476b10dd1fa1882cd55d880ccaa2212c3f48eeaa4ca5218c25772ec00c85b2cb6487c44d4bfe14417a469e Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37440 Depends: libzenohc (=1.3.4) Filename: ./1.3.4/libzenohc-dev_1.3.4_amd64.deb Size: 9186394 MD5sum: 9b67699fd4e330ba3ed595d1153d743a SHA1: 1182924160687fcb96a9347fea715f3e9b6f1c11 SHA256: 7be723082828c16e15ef7502c6a68178cf07594ce5f6cef548075d5998e7f56b SHA512: 0500aea8306c8354e51a1d70aa5d5d67c2b028c6b18930076fdfa511ae0eca35b2073917384431b4d08122f218a86f571c39e347617a7adc877898e83e578f9c Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 36765 Depends: libzenohc (=1.3.4) Filename: ./1.3.4/libzenohc-dev_1.3.4_arm64.deb Size: 8858774 MD5sum: 08dcdfdc7d765fe40ed7c9560800fe04 SHA1: 1efadc3553e4561fdcdc13b1799246dacabf257c SHA256: 549f8d569777e9d7a6e6ed886055804af05dda5a7480ccd3f73f84872dab9a0c SHA512: 12335b7eb4551184f66a1ad88508712117b32f9ea930bc7c5642ac9b0d537b79e399171a9ffa6788c6cd4fed4884e47b13e5127091a20abf16d2036d8708fb61 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31006 Depends: libzenohc (=1.3.4) Filename: ./1.3.4/libzenohc-dev_1.3.4_armel.deb Size: 9640342 MD5sum: a72cfb6f8bd87d13c65609aeb932ca57 SHA1: 781766f9ea108b8efc0491c7aeaceabf701bb2f7 SHA256: c2a0b1fd8b5de4e25fd9d625435cc1fb7b09ed6b4fbc66bfef0d48da39394131 SHA512: acea5b710126b11b82cf533df61b22b8156b0546363fdfb0588815120e742973cca04f4252f3320973e6992336dd5db41fba95f2b0e415978a8ae15adb2ed1a0 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31153 Depends: libzenohc (=1.3.4) Filename: ./1.3.4/libzenohc-dev_1.3.4_armhf.deb Size: 9761034 MD5sum: b3b509a6bea4f14cd7a938df890e5e05 SHA1: 4c3428f298b9ff843d1d2a161a2448e51159d3f1 SHA256: ddfa67125691f79628c357afe6505368c0aa194aa48b6833be98d51894e45f99 SHA512: 12fc406f4faedc54eb94e37a41a3ca7e87a07418598877441fad837d2979578b6cbe4de2656ed6e4894ce550d06031a0c2cd3bf46f00225962a9142ccc41064f Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 35218 Depends: libzenohc-musl (=1.3.4) Filename: ./1.3.4/libzenohc-musl-dev_1.3.4_amd64.deb Size: 9067414 MD5sum: 1b1f8b7012e3302e08f736c128f0f801 SHA1: 4c9b678b09d1a5f4a070a17d1aa351c6ac68e548 SHA256: 301dc20bf168393cf29bff24c84556f18bd85455de602ff1696c0660cf509a0b SHA512: 1a9ca01c78e6a413e334a54f3ba76ec746d19bcf4cb93710beb99f94bc9e75bc7de3331e03cb40884859384feaadfb116e6f5b36d32e467e22ff81e5f3b44678 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 36074 Depends: libzenohc-musl (=1.3.4) Filename: ./1.3.4/libzenohc-musl-dev_1.3.4_arm64.deb Size: 8728232 MD5sum: 86d9b3d01e59e16ed126a2504ef97a81 SHA1: 0f35a346536215384c16520c8025d75a2e3f8503 SHA256: b9e53b8b47b572373b4d0fa63c520dc3c132aee7d85de700a15aa2782194d03a SHA512: 857f91b290f68955dc0175cc63cb1acac72741fa16653fc476290ada2514883378b365cea22c1442b025048e9c0c80e94e8eecc9b90918a08a443281596bca52 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 14397 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohc-musl_1.3.4_amd64.deb Size: 5734042 MD5sum: 3e907ba1bd44112873b0e2a35c657c15 SHA1: 9a6288bc168bf033653447d84c06dc27e29e1f8a SHA256: a29ad13a02eec3d5adbc42908ecf9b15e876df9bc5c93cbece484fdb56e06903 SHA512: 1c4ed399a33e8d484b9c113845b7b21e506b4af967c38e23a391dfafd7049b1f402f5a218d1978fab22eef8947e519a64036a5fbe785d59599f739874a260de6 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13416 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohc-musl_1.3.4_arm64.deb Size: 5449392 MD5sum: 64dc0d0969c91071dbdad35fa919d915 SHA1: debc2a6ed064e684ef7febea63f72723769cd65f SHA256: 80481c306297d5ea76acd1e69ab84478e3d227537355d730f34115c18770d656 SHA512: 3c86ac190928486927f7c526020a9815d157b1c26c167a7f4fd086e00a9397d564af00991330e54a6df93d52b17da763698bac7f0fa033f36121d108411761e2 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 14403 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohc_1.3.4_amd64.deb Size: 5727740 MD5sum: 3a635a58e2af2534af8ce6abf05d1230 SHA1: d594f4bc39920e4dae73a91bd7705869b697272e SHA256: e1268495c8141ed5c6b2d7a8d9f4fa37441a9c3df129a98f8598e728442606bf SHA512: 4d4f7080b1ccf8bbccbaa71c635559ddc703c2c2a690380c250b8dbf31e0a99028ccdd0539750790ddda7d610843caa17e65699adb67beed886ce2daf15ae261 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13426 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohc_1.3.4_arm64.deb Size: 5473506 MD5sum: 460fbead916ac068762cf416c2c21152 SHA1: bf5c1d8a1e2eb87aebc131fb320408535ffb8a4f SHA256: 6e0e68419de93dd70f7dd0944a7329aaea89be4cb2284afe5de4280cf0d4fed2 SHA512: cf5b51a7c5d1e15c0727c616eb1a41cc27dd92d5eb7882aa17b3c351899f7f4d1065cac1095fa5b6652dbc1428895a23ec348d3dbf6834023f455ee24960beed Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13787 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohc_1.3.4_armel.deb Size: 5782302 MD5sum: a58aadfe5c9f3f9ed102f77785feb070 SHA1: 199463220e17e5419347f17e4f8387d6b7c8b35c SHA256: b25bfd67144ecba4ccf0f20faee64b60bd4807daa80a5dc4fe77ca2ee30a92ec SHA512: 22bfa18748a942ab7e6f09879faebcc951c5f972b68e30b6a47eef4b62438c66ae37e9de596105b066ec6d56798af73f2111332abbb6dac72bd853e670dab99b Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13795 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohc_1.3.4_armhf.deb Size: 5856960 MD5sum: e67686a678a02e79cb059e4594c9ceb8 SHA1: 667e3072c08d607537925d710941c215f12818b8 SHA256: f20da548f250e3f8d27cd0c3d556637a8cdc84bee9a8401cb0370c4f29521f13 SHA512: 64c4af4fe588439bdec65aabfdda0de0ee37518cd693c46b0c6d880e5aafb2b452aaa61a7e95360e0897eddb74634bcba9ed0efee4c07c94c058042ad356478f Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 450 Filename: ./1.3.4/libzenohcpp-dev_1.3.4_all.deb Size: 57994 MD5sum: d73214c250c77ed21cf6acb4e8d0d17d SHA1: 837b83a67ca14a41c7e2780ad80aa35b6118bb2f SHA256: 2e9d373c4802984b6e66e5d3df451f08d51fbe8399437fe658e9995544d10542 SHA512: 45bd9dd8554b089282a0f72bd5351c08364f41e9ad085408e4e1be06869220884dad3031c9b1bb6df2b6c3852e59c99ec793fcd6f9b4057392459e0a5bfa91d4 Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1258 Depends: libzenohpico-armv6 (=1.3.4) Filename: ./1.3.4/libzenohpico-armv6-dev_1.3.4_arm.deb Size: 252808 MD5sum: f2acc589e43bd23621cbcf01f8b0616a SHA1: 98271a76975b9d42cb4de099bba3d3ccad627fe7 SHA256: 2820316d17abd881e458d2c50daf62e7795bd2ec69e6b8eeb14b1a87fb824ff7 SHA512: c60bedb2e2fd37a7e11b28f17c1e44c2873e60a38ec27b76df510e6f0cef7689f96ce6fbdbaa5602d1e64e4f7f384e2dadadfce82131574f1f1ad57288c19265 Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 364 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohpico-armv6_1.3.4_arm.deb Size: 150140 MD5sum: 8e48f10906e22d02f991d7bd879d69ff SHA1: d0be2787440bab68855d0603926a07812089fe32 SHA256: 252d55e7f898327344f3b740af7bbce4e993c1ba6c720078802088afb368f182 SHA512: 52a2afac7d95b44a3aa23ecdb12dd00f84630cb036866b174bced6cc65b620d1a47b0841c97da2de9fa63c63cee3ab8ddbab0f7dd38f29f70aed20a66b2b56be Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1250 Depends: libzenohpico-armv7a (=1.3.4) Filename: ./1.3.4/libzenohpico-armv7a-dev_1.3.4_armhf.deb Size: 251000 MD5sum: 539c3a1fd2568fb29c3bef2bcfa3dd2f SHA1: c09ed0fddc04c988cb68927c6386efde646db68b SHA256: 04cc6ec4202dd51ee1ab39519062d0aafdec5909ebffc8ecdedc612deefb556e SHA512: f12dc75256bb152976bbcc57e6978cbdcf2659c88fec9ab7b6ec2f6ebc1938e560906da217ba3df5ab095eb8ace9213f71e1e975ecab5538e7b79e86e8085e75 Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 364 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohpico-armv7a_1.3.4_armhf.deb Size: 149320 MD5sum: 35d10d9ece11292b103cb80c5870532c SHA1: 32829ad45e56e49bd0fcba4292077bedc4f1ef38 SHA256: 58ea7d796813f4771612e7d4dd02c43c8ca6d476e7d4c10bbd654c3060aec2cc SHA512: 52372e01ceb93d4de04295b65ca753ba049a8425424af972c30f955647c888614f1a735eb4da48f2d97f42659b6df0c1ad5e6c7aea45293dce9a1ccba59d84ed Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1512 Depends: libzenohpico (=1.3.4) Filename: ./1.3.4/libzenohpico-dev_1.3.4_amd64.deb Size: 300672 MD5sum: 9da393bdd37dfa01e8d9b6c8b694f1d9 SHA1: 1d91b4a6e9c4a72d534ace009917ee1f2cd1147d SHA256: b871a35aea72d14543d7e5c80f2e53b312802ae8e1c950d7b0ac242e0515f931 SHA512: e0aa701fed5273e5c7d067b8c08a02da4cf62c9c57d678af4e84b5e9e0aeff70dce0c259adb3a593758dce3f2c9e4dcf283c8699d3296bb7a2286009658da991 Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1257 Depends: libzenohpico (=1.3.4) Filename: ./1.3.4/libzenohpico-dev_1.3.4_arm.deb Size: 252248 MD5sum: cce1e6a93c297380ed75ee602453c1dc SHA1: 94340a139677f92c80b6857cec60c4946e6252c8 SHA256: 23eef8f53455c5021120988a77b19b22b45a36c59af85a61e430ffefa9ab7a77 SHA512: ee0fe53689d08e157595528cbd6ce90797ff9796e61e04bd9eb953c645f3f886cbfb3830e455917383164a92e3191c9938983cbff2336171604a57073b11cb76 Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1523 Depends: libzenohpico (=1.3.4) Filename: ./1.3.4/libzenohpico-dev_1.3.4_arm64.deb Size: 297108 MD5sum: 37441c9854ed88187a60df33fd5a3685 SHA1: 87bade50ba469410a76862d5e36051acc55165fe SHA256: 18ac303e22ab49a8a8fc85d0d423f180e4c39c7ae0e99b270e3b522cf57c952a SHA512: 6527c84d4eef327718929e83d37f13f13e7381d25f2cdee20fa5c3e98c9f03757e2e0b5086c2bf7dfc154a936d32f92803ddd4ad0b7cf0db1947c8d6af55d374 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1251 Depends: libzenohpico (=1.3.4) Filename: ./1.3.4/libzenohpico-dev_1.3.4_armhf.deb Size: 250698 MD5sum: ffce9cb74c5320c8838cf962135f8f15 SHA1: a2631e1f30ca80a23c8d441bc07c68c763dc9e5c SHA256: e4f3bf14e60f6ed21a200995b80e657d349142e0f732ec402b8162f0502d333e SHA512: 244256ac8d7080df34c885d0ea50800a9000f8d81d93325baf7ed7efb90931640e595a7f9ff4aebfac0354eb1a150069bbf90e4b6e5185397f283c55f3ae1dcc Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1482 Depends: libzenohpico (=1.3.4) Filename: ./1.3.4/libzenohpico-dev_1.3.4_i386.deb Size: 327846 MD5sum: b50eae6b43698a549ef73205583156ab SHA1: dc84aa47ab18534d09ecbc036edd6048fdac338e SHA256: 840ddbcacdac9c16907a3a0337581faa76fcfce8ad7eb22145e70ab3891ffb39 SHA512: f8708ed10945d801b7f643824cc9dfde3d425d1e4de43e7b5b3bea79708f278aac3100cf02fb83dc66462a85e7c50176f014e28c60b8a561bd07faea990e9315 Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1406 Depends: libzenohpico (=1.3.4) Filename: ./1.3.4/libzenohpico-dev_1.3.4_mips.deb Size: 285304 MD5sum: 1e3d2e79581ccdbbd0013c04cd30d6bd SHA1: 4ddfda068d12cf68c14a4a67d330137ea10b8084 SHA256: 4acee8d8b12040f4292c19dba593e9a9ba4c3882562faa8372b5c5cb6253d2c1 SHA512: 643a488c81b61ffeacce78d8b8c3e815e2a8ab1fa8ce25a899ce502c99e8bf65e7d9b9e2a9f5c288e7c6986c4af7d839e26f7a18d008a1a18e638fbfd04f8bf1 Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 496 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohpico_1.3.4_amd64.deb Size: 183794 MD5sum: ea87ef7b4f026d22d40b4a882064cca4 SHA1: f441b22d1c9ec88a282536c30fd77573bda0affd SHA256: 0dba5d013647da7676f595fb2d9f13f6afc3659b94b63c3d66838f9975e1a87b SHA512: 821dabee6246cb140d993205b8cf4073cc4be2dd94b1de0a19d1f48160d4b419eb47e578393ff42dd846889662d58bd94cd0294ecbc80613ab4155da549f3638 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 391 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohpico_1.3.4_arm.deb Size: 158270 MD5sum: fcde21b597ff3c5596911fc3038af68f SHA1: 1b79b15a03a7735f4ff74eb80c3305e008dc4d7c SHA256: 84020a14e183475c914e01b91ef9091a93df92ff23a6a5bd0e32bed06a9e411a SHA512: 34d6f17d5a453e26fa1ba576cb72b34f1c0c0f1a16cab4d88ef34448508b16549f76c2e066800d19cc074689d7eb5326b85296d56da4732555aba2e9e51a771e Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 506 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohpico_1.3.4_arm64.deb Size: 179874 MD5sum: 3e7078c8b94fae288c48cb7a5d3ce175 SHA1: 5e9e24c94981d13ab5174535da3081e09ea8d605 SHA256: f803b6a6f800ee75344d272ae2b5e02e0144a4e0a0cd8a90bf2dbef624ec427b SHA512: 8b7bb1922256acff77c31bd319411eb2c86f54d89ea22c4034c0234f96711bb10b2f946062b9fc1ea5648e42a8a1520070e466f32ec3735225b7012d06b38bdd Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 366 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohpico_1.3.4_armhf.deb Size: 150434 MD5sum: a7c291ac8abd214359a74448b14e9afa SHA1: 04c951b041e5aec0b9de55f620a4708f20bb963d SHA256: 2a1ab183d2844c2c6cc24c4d3db679bc4efdf36314abf11386219902cce26850 SHA512: 13c146c6f421cb6e4e914ae50ce0dd78f1dcde3a3676512530b95743f7d416638d68fa47e943bbb116474a9ca34a60c4e99047adf7f9e291d16611e106485d6d Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 522 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohpico_1.3.4_i386.deb Size: 209814 MD5sum: ca9b65a626261952fc3003b71e900edf SHA1: 0ec91aca01bd4c37426bb624190f3c68c2e6f554 SHA256: 480771c2ad072d086ba700ea0a4cb500f623e2f910988474e50de02982bdf48f SHA512: 1065808ee8b2e1223fe26dff63825cccee562d418ca6b944d161477ecf510956a29e416b7506f7864ae20a90edf94ba6bb4e97cac1ae190c4c20e0741142ef28 Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.3.4 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 476 Depends: libc6 (>=2.12) Filename: ./1.3.4/libzenohpico_1.3.4_mips.deb Size: 164798 MD5sum: be4b0f38dcd8292da6970bb7406b499c SHA1: 2682265cec9f622f087a92ec60fe79974f37f2a2 SHA256: da8ee1f471d6ee9ebca37304ed42faefd9369e8e4d256b591f8f7b325bc2e561 SHA512: b4d649c53444a31d6daa410b06d55979231162a6e158f56233b34849801a9a7e37fcede8a01007e46de06e76fbe14f52586371de60154a7374b506397e45c77b Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15521 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-filesystem_1.3.4_amd64.deb Size: 3985328 MD5sum: f827d2b6922bea27d8bf4f56dd55961e SHA1: 692cc821cc40fcdda24480548fd843bb5e9755a3 SHA256: 3b25261399bc3008ed1a3d98f0abe7db2b8ea3d3538a45adcab6e220dc123912 SHA512: ebaea1a5eb5a417166a83a6f8f05e96c6ea01c824c360e67346621d9f546af1cdfe1edaed6f661af7409b13aa3b74cd4a500754c7549e680585e4d900574c75c 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14117 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-filesystem_1.3.4_arm64.deb Size: 3442908 MD5sum: 072a91eccab6d407793498483fbd7789 SHA1: 19e1b05740c152ecd42ee92380f16f79dca2958b SHA256: 6a3892bdfbbe3dccc99411bf29e6ee87748a86b9493ad9f657fe58c438457067 SHA512: 78882becf96c89f61b82c7014fe9b2bb16fcfacbb0cde3cc59fdb0f791a2093459afc44cc1d9853d39acbe70e306466ae4ebdf5f5fda9b01946cc488e136811f 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13285 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-filesystem_1.3.4_armel.deb Size: 3391168 MD5sum: 8e2fc449aa126ab0c493b073aefe39b1 SHA1: af10fbe6cf7c7c256409aadcb52f8deb3078d6bf SHA256: f3a5b2f245bf1bace497c6dafcdd92b5efbd276dd25e536068a40d9b1a120450 SHA512: fdc411dc74358e82456e9fa04279354fa5dd58179fecb78530b637a14a60a4a696d048325083d02f554b01f7f496396dd249c9f2538a05a27ca29c4faddf3b6c 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-filesystem Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11241 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-filesystem_1.3.4_armhf.deb Size: 3504360 MD5sum: 0458f70748eaa080b2d33efb66c6a650 SHA1: 493788e3f98de290fee51fd71a8eacd27b55954c SHA256: c25d153b27234652d6cb79157b56081848368215beb8c27141c6c915a724a216 SHA512: b407b5270ae00c0abcd3de617729c03bcc07d112b7598ea3b797462cfa3847e5c1e731baaf2445b5f62e235da3c30f80cc1d5bf689367154ca279d6056066863 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8056 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-influxdb-v1_1.3.4_amd64.deb Size: 2076708 MD5sum: 07cffec6e708f518d1e75d508f57a192 SHA1: 2e654b3ed8915627d32d38615856aa5aeddd7ecc SHA256: 83ac56d2d08d806df19be793da77c368af1d3175bc7e6e90cea5a1013492f197 SHA512: 688a5df0ee6d735fc46623f5c33ca25c1c2ccd39ec34920c7038d4a835cff83469e4f09c6450c1db1640490d4dd3a055a94b418636f724ba53e92d17425363c1 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8007 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-influxdb-v1_1.3.4_arm64.deb Size: 1899228 MD5sum: 2ab3a3a03c96706120e5bcd14651d94b SHA1: a847d8771f1deac40603155a5387689b92832aa2 SHA256: 9ead76dc7ad0512c09158ddf9b1a8edd4e864ec3358e60a9bab432c4bdb08a05 SHA512: 4224cfdd6b2143abf9bcea7d4718e7cdd28701a1ed670d1ac54ce6b056fbefc5f456c527d4c2f4c46f99ed897075670ee089f107efb745fd59c997b285640222 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7120 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-influxdb-v1_1.3.4_armel.deb Size: 1727392 MD5sum: a04beb6df3317f3bca1a5ebfaea21907 SHA1: 7aa59ca9d7decca17d6e738ae9969aadcf72e11a SHA256: d49d9931482a6c4eabd12e687bbd4ab82ddab8e4fe3c05e0620f6d4776971e97 SHA512: 66b705768cb77c4a70669d11af57066a735ceba42e0de24486b2b476b453c2777b10f4cacff71bef9a3dd5cea8382bdc96c296d144d5099c5108c9b85519d6ca 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7017 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-influxdb-v1_1.3.4_armhf.deb Size: 1722336 MD5sum: bf7aa751a503ae4484a15cc381317494 SHA1: 0112c60f45bb4abb1b6bfc8de685d1200b23a893 SHA256: e0deb64987451d6e093a58f519caaef789a4b640c5ffeffec90db9c20f486d03 SHA512: cbd48037be6ad662e9c95b204a02ce533a85429ea96f49d2293849f8d9e134fe389d015ac9242291f4125cc062c29dc6f61d4c1be0f97158a1f5bdb062176f69 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10764 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-influxdb-v2_1.3.4_amd64.deb Size: 2793644 MD5sum: 1f1f6bf91a3cb97b1d7bb890076c2d0d SHA1: 193ab988ddc0b829a1c2d3e6ab259dc3687a4400 SHA256: 9440bfef05ff1fb81621ccc4e56c16262a8ebf2951540bb01c41782267e4265d SHA512: 115e8ca646712faa6902e30b9e3a5b254e7c16420646dc14ba73836aacbd547a965b4ea3a9dfba9b0290b8dc7c9b430cabcbd2c9550b2dbd3ebf6a4040ca89b9 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10716 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-influxdb-v2_1.3.4_arm64.deb Size: 2600780 MD5sum: 6e9a226698190f6efd6c5069de7c99da SHA1: a0179afacf8f3617aff7617d5951b0b8dfa7fc5e SHA256: 11f5abb51852adc80e8c71d3ade4656cd14a1a10f06294bba197025b92b53c53 SHA512: 8618a9ab731b5a348feebfe6d6c027b73d050dcc0cd704e2db425f4627e338b3b309310d18b3da16058ce72cc932c857a21993a6222650aa820237a6700f4031 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9665 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-influxdb-v2_1.3.4_armel.deb Size: 2401680 MD5sum: dd821792ae04eb51f8f00bf98ca89254 SHA1: f7b27370f8a2128d1e13afa1fc6c531ec2efcd21 SHA256: 40d1b8397ac3629c7a1bd61a0ba477c44fd4ccc1dae089c0a1b8f2ffc97a77a6 SHA512: 32badeaeb8a0201c87c43b7f4c394a43bedf06cde7c50a3de653202dae2d9697f7420d7d9b757be9c78cc39fa843be5c4ae7b8ad585c4a6b71ab68beac67a582 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9522 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-influxdb-v2_1.3.4_armhf.deb Size: 2414364 MD5sum: 4ee3e0e11361c0fdde1b6ab6d820a432 SHA1: 17e8a87fed0d8be9bf575e61dcabf0a5a3367608 SHA256: 20a25c0815cbf0e5c9da8a9df264b16b8e18febe1ad881659e386e0aff9c5b60 SHA512: e45625b1f2b4da6d55023af1e47353633c71ba4a79237497ab20326b4abede578cb0c8a1ede12b3a14020d75605a57d7067fd656926b57d7132317a2fb48be08 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14472 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-rocksdb_1.3.4_amd64.deb Size: 3766728 MD5sum: 36f82e4e3e4d98012cf137e6430c4fb9 SHA1: f8d5018f89c9cd28c63016e4055927bb099e3d28 SHA256: e35b96278fb97b79f55e6efc3a77e15b389ae3e7a26836df7f30a543561b3070 SHA512: 0a5cb5471f3cb9947ef69f78575e34c68c80a08148214df21cbd38e0aff5d530805a0413b5a9ef6bfccfa13bc13194ca521687dd72bb60235c74dbf2d9bf6093 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13025 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-rocksdb_1.3.4_arm64.deb Size: 3247488 MD5sum: fe7abc39309d7ce155c670949fb06190 SHA1: a2ff6d7d11154eb8c90ea44f7f898897393b4110 SHA256: 314cfb93c8e05eddf3a3aa84ac8a2dfe03535230d371e3913e9651a447db52ad SHA512: 40751a143db5c14eeb638afac1e5d69427b478afe9d149b16382580d87dc160caa85986fcbba39b09e035d64e608df1d1a24c164ea13ac4fb7919256bcf9d4c7 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12432 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-rocksdb_1.3.4_armel.deb Size: 3217048 MD5sum: 6a2750334fefc8ef0473e1d054ef4320 SHA1: 60df3db7469cf7d18597e98ee4c1de5b8d7e8f43 SHA256: 91236cb65c7dd55bee50def44eff45d71328de1e4a4e040d23be28e602dc5958 SHA512: 2d4386ddfeda08b05b28671b13b24dbc259989a6c8047d0ad01c24f979464240d248049e7b72936546fdb32e2764c85838591df22079b348a43d70ee44f09daf 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10357 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-rocksdb_1.3.4_armhf.deb Size: 3341572 MD5sum: 2f032b42e49ae298cb749e8050eeecb2 SHA1: 8c06a01ce718ce3745c57c82e7f1ee49c693438e SHA256: fcf831dd730fd0f16dc7d085c5494c9f0dcf571c8d281917da6bc096d151b425 SHA512: 07b032dadd92b32b2fb865283f3c3873aac786a6b107c452958863c432a283c1cd725d68c185bd3f0c24b137acac4153477c9852dff936c90eb1c931ce594e51 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20346 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-s3_1.3.4_amd64.deb Size: 4425612 MD5sum: 16819564d9a779f06a70de68e92dc0b0 SHA1: b3a8c9e27aa5a63b1b9f150971dbdba44e09e217 SHA256: 0216b9064c673088818c4bae14dd671e82c1118610ab86b89e1f42bcf3c580e0 SHA512: c7b257bef70d249aacd9425b81d9982fb6ac0f2792be1b71816dca1b5cdf9eee7e95e0faf29c5a087e96fb1c514c61f7ed385b8c5c95f5ae5d4f76d6d2682ed2 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20567 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-s3_1.3.4_arm64.deb Size: 4205340 MD5sum: 7c5c37d462bced580f4de3cef7683375 SHA1: 597732b8c1f320e1be756c29803f742e24fec855 SHA256: 99f7e6a1595f0e3a3e281ab857160436bc7d64082c10f662923d8af6ac571a18 SHA512: 6c3d7c7508b7defcc9ae9bb0f276fb5045aa68f2e74a119df5a22d1ed90dbd228be20ae4aa36722043dbeadb9abbe1eea5b25a439d73108f1050f24fefe943b9 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18964 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-s3_1.3.4_armel.deb Size: 3903420 MD5sum: 7a1b1aafc026b0ff7f8ca148ba039c1c SHA1: 73d54e826d1ad4d7677de022490eafab844b9189 SHA256: 5cac282767f599e53dff25e11f564daa7fb9732c1d273f64308106c1ca989a1d SHA512: dde85397ae6ce0a2e29d21073aec89ed7b1d467c30c6ca81162cd1c5db517509d7506157b525472584e39c385f741006b991ab49e20823866ddedc45f2ced6c2 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-backend-s3 Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18712 Depends: zenoh-plugin-storage-manager (=1.3.4) Filename: ./1.3.4/zenoh-backend-s3_1.3.4_armhf.deb Size: 3947912 MD5sum: a0852283a7a44f264c70d46f7eab8d05 SHA1: f430db754f31d94e5cf73d4bfd0707f2735e1172 SHA256: 0e7598142b62133a52a70d065200f8d6fc50115a9119b95b2c0d5c3fce194cc9 SHA512: edb1aa2fa872499e026bf40adf9f058020b40a27d87986060edd210f4a3dfdeb37faf5459fc8b6079cadeabad7268c11dc041230ddfb2f368fceded17d9e8017 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 ``` Package: zenoh-bridge-dds Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16224 Depends: libc6 (>= 2.38) Filename: ./1.3.4/zenoh-bridge-dds_1.3.4_amd64.deb Size: 4696612 MD5sum: 2fdeabd41a78132b9c95f1484e57c52c SHA1: e1311a41f48ac356728dbe765e012b9591386ea4 SHA256: 520ac81a577fbdf50eb1462be8107203f503f3b04700c102ff37de631b4c555b SHA512: 72d4816b847020b5cc9d36ca7cd788eb0bf5bb6fec01158afb9fbf1f17c4618a3cdc75b7b8ac13141d9ca8a289e96aabc324ecfd7b35ef6246b70572edd5fe33 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14979 Depends: Filename: ./1.3.4/zenoh-bridge-dds_1.3.4_arm64.deb Size: 4198744 MD5sum: 65de2e7cbe7e2e4b6c5aeb9ea856451a SHA1: 47a1df65e6967cc1371a60ec492013867c8c3f90 SHA256: 851724de98f72b045c95c6aae04f1ea7086f0cc54cc29d1c2e5e63850776ee28 SHA512: 0cd9a971288e17cd344c5d5cc4050091fac7402444839e31793633f7e78913c2d8404850dad8ca69debcd55808e900aa3a326718b0e196c328d888808909b6c7 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15379 Depends: Filename: ./1.3.4/zenoh-bridge-dds_1.3.4_armel.deb Size: 4294540 MD5sum: aad7c794cf137f55e49c0df0442f5cd8 SHA1: 7376cb20a41f8d6d13c738b526cfb9c5162d6bcb SHA256: 6c8ec9ac9891cbd66829c91486c7d51791d7c09ba5e465fc9218cae71815c0ea SHA512: ef356b89f242c84688bbb7a58c918eb8410c0eabc43776846ad0fa7f6907da60f4e51b1387a63732169d65e517688556b920181c7c0e771a1aced104a30fbbda Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14822 Depends: Filename: ./1.3.4/zenoh-bridge-dds_1.3.4_armhf.deb Size: 4310196 MD5sum: bff62123374be1b38c85a05f7edb279d SHA1: 2eda9d180d2b5b63ad4a26a279326c82ac11874d SHA256: 7729793caafa5e42f700344b58d7504f405fd2789704a88bf1ab9166f064af25 SHA512: 7dd25368ad86f4e4513d33e2e217e990beab708553d38ad114b60e86a672b92dd175cec6a8f564c5f296f4693fe7f4e1ad1335cd7e5b9795eff60e583451e48f Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-mqtt Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16145 Depends: libc6 (>= 2.34) Filename: ./1.3.4/zenoh-bridge-mqtt_1.3.4_amd64.deb Size: 4376260 MD5sum: bffd8cfb09aa9828d7ae7a109ea4e011 SHA1: d1065e206cc730a4b7bde9539e23b17b1e432db1 SHA256: 2fa0ed29950f642ea666dfa81bcd6aa93fe065863f860e47dacda6a122b47749 SHA512: 5dc7e4bc91ddd043e079d73dd760f8ed825efa48331f28589371d8ed6dfaa7012d5bb06e981a20dc1d143db33a00b6ae0c2ad398402c2b12b0f48db7bee74993 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14844 Depends: Filename: ./1.3.4/zenoh-bridge-mqtt_1.3.4_arm64.deb Size: 3894988 MD5sum: ae8780ffaf7f714bed00852619bcb489 SHA1: 45d3df00a2ff27ddf14643d01e809bebfa7e7365 SHA256: ad77240a96d0df52fa00aa87da4785d8b06cd887405957cfaf5dd880a1995ca9 SHA512: 075edc79e49c5aec1091828332371bb7e94d1e26c41401a1d347d44baab82bf3eb9bb65351819efcf4e117843972b3c66934aa8d42a3e94d71ee35e413d2f1fd Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15455 Depends: Filename: ./1.3.4/zenoh-bridge-mqtt_1.3.4_armel.deb Size: 4015160 MD5sum: e286106e2e1aab4ebebaa4b1f0cf40c6 SHA1: dc3e86a3f6115627a9d829f9da0ede255e5076a1 SHA256: 2df3d5942ad37c7b057146c97a68db2c90de4986b321e08a77ae991fab24db50 SHA512: 812c67d01c932f4a33a7eb568c72a916db8c4f8ef5b219e8d22ad14ee33a0f9fec5a7650e27c6e020fe115fba5c4d70e39e7a4198cc6ea2f382b149530bfbf17 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15135 Depends: Filename: ./1.3.4/zenoh-bridge-mqtt_1.3.4_armhf.deb Size: 4006604 MD5sum: 37bd4a466b93d0765e7c9ebcd397c57a SHA1: 16e24206c3ab74b2abbefebe7c49c89849f13864 SHA256: f2a5ba066e78bd43477ee976a9633eebf1b52faaf53176b719242e97164655c4 SHA512: 63a8a81f27faf7ccf5e99b8424ca91eec67e523bb2465495e2d86599613e92ac13ae5d7ad1a47f42bcaab7cc59ad96a54f7f11ccf0859fb6099efd2ee3e10651 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16821 Depends: libc6 (>= 2.34) Filename: ./1.3.4/zenoh-bridge-ros2dds_1.3.4_amd64.deb Size: 4802244 MD5sum: db8c2d73e7ad2560b6ca1917a4338f9f SHA1: bd19dc80e300771c3600ea5999723d5a0ac99b87 SHA256: b93041af083079b4e991d0a132bddf62ea8c284983b35768b8d940d46037bf07 SHA512: 42338aa3a0db4551a5b98db322b7ac8a45123709a5152be00daefb647a09467c407d0cb2c8de932571056be9596c5f5d35797ae43efb16bf9864eafa412256d6 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15507 Depends: Filename: ./1.3.4/zenoh-bridge-ros2dds_1.3.4_arm64.deb Size: 4296740 MD5sum: 5133daefe934c682d6f86e4c1932d673 SHA1: c1fae87291de37baaaacdbd005c10e04e9e0d840 SHA256: 8d062bc28347b7d6f92efcf6d330fa2c5e5771f568d92aa77bcaa6e39cf177e9 SHA512: 822d841b95f1008b6342a9b26fc11fad79c5d7296768ecf3063501ee6d40013f4a6913c621f90acde1a97153b3f92861dc761a51881363af4a5fbf5d63dd3ff1 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15889 Depends: Filename: ./1.3.4/zenoh-bridge-ros2dds_1.3.4_armel.deb Size: 4408692 MD5sum: 0fafe6fcd751d17cbbc6935652ffa7c3 SHA1: f20331816c99ff7db26ae65d20bfb5162778e374 SHA256: 40d789769527058cc4742920081d2320ddc5ffd908949aeb33f46d6bed2c2374 SHA512: 423c5e5d8c742248ddd33071fdb9bd8157828ec7866060179ddb5a1f4350ef9f5bbb547e2f4f325e4c58d340e3afa6d78ac95ca53acdd295950627214cfef20a Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15345 Depends: Filename: ./1.3.4/zenoh-bridge-ros2dds_1.3.4_armhf.deb Size: 4416980 MD5sum: 8382fc6bad9755e4861d37c52698aa1b SHA1: c0286e1df09ac509f2c9e9408a55f8b221e0d100 SHA256: 0720c463ae4525fe8281717ffba755d827b1dfe0bbd20f4a58c75dc6cf4596f6 SHA512: 6aaa35839977a8bbfbc602210fac7f03d807b3bc0c084aed40822e30d8628221167ee74e5277967e1cbb47df3f5102160410bf0c4ff002ada363d718fec02d67 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-plugin-dds Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6358 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-dds_1.3.4_amd64.deb Size: 1722424 MD5sum: 3d84b75d4dcc88ceedc6b5a72ad32764 SHA1: 844f9fdff65fce7f585e9c88045b55508223f12c SHA256: 78ac8776f32b923274e75452b8b24e48b7e750e45b835b86c331d8f008815e34 SHA512: 697c573e2e72ea98fa6611650b338b4945476a7cb119682059bbeed5bba5062a49d25a62405415c64225d32fe5234ccddb3bd5223540c0385bafef3f83e04abd 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6287 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-dds_1.3.4_arm64.deb Size: 1570728 MD5sum: 7e6cb99b6da9c2ae5125d38cc2e8f2bc SHA1: be517b7449c438065770a0296d574e415ebb6878 SHA256: 670711de056906a8688c47000b322d6f2c81c158727cdea93369bd3dfc3c927d SHA512: ed4d354f4fb5f35452afe9ff9775c099939216b1dfd3019fe714abc5d30ca3f74b9d7dd447457c86e8a563a4057c6d9bb0970687799c3dba4537d946426957c7 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5866 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-dds_1.3.4_armel.deb Size: 1577144 MD5sum: d04a707ebba78e8896c2427303cd4c74 SHA1: 40be733c289d7118a3493fb7cd99f6acc57be72b SHA256: 6d61f1ae2bac04703a190fbd21e20b81ec1072a42e672be22afba24e3fe95583 SHA512: 551ff5c2ac077fc9f686fb0f715c6869394c4825d1355d09e94b5844dbd4fb2f6884477fcd736e74323dc7db20fc5a49649710706f894aebae939e7217ca64f5 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5516 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-dds_1.3.4_armhf.deb Size: 1594496 MD5sum: 27271ff50a93b6cad419686fac000ff0 SHA1: 890d052debb36c192e9c23b35d6cf40c3cb0ccc9 SHA256: a366a820f40d12b41d687e1fb45e12190bd2974f69414e82317d910ad9356c22 SHA512: d9fbc0dc9cec7982493862e5911fc7467f6c165aa89ebbf67f580b841bbe6e670f14131850ed335bbeff98cd1dc09952026f039109f633576456d28dbaf722ec 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 described 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/](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](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 maintaining 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-mqtt Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7688 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-mqtt_1.3.4_amd64.deb Size: 1924528 MD5sum: edf3b8eada2df8f55c204193e9d9a84b SHA1: 2af398691ce5e3bf7abd5aa1fad2b2d8ef7b6da9 SHA256: b89cccba905148d3676ae7fc8ec7fdba04c427c0940828c323dd285c247e49fb SHA512: 342e7d18387698ca30d59dc91c9fc13b37a8c43416c511963c88110b272ed9da422241c2e35ccc0b0d8b974deb5daf0eaa47fadfa6a3d750d55fd1bcd02713fd 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7459 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-mqtt_1.3.4_arm64.deb Size: 1752884 MD5sum: 7f105edd452fa84179e9f5d2625eefa8 SHA1: b20c77eb57b2df1502dd43247544311ac0de4cf0 SHA256: 056c269bb1935f3e02dc218dfc7341db7ad2d2a5835a120f8d48eaa219af21ba SHA512: ae5b427e4bce02ab8b4262be1ecd99e08308d105451244d36deb05ed66019b92913dca6041ff667c3a3bd523641b3b773737bb27d771fe83e3adb351d7e65360 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7055 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-mqtt_1.3.4_armel.deb Size: 1636284 MD5sum: d0544977ea40f4120943fc97dc974957 SHA1: 987c847cdd7c5fb443909ae038cc3b264bd7dddc SHA256: de96cb35a82549b3ad26e497a0cb2881625767d089b0794567bc2d711670ab96 SHA512: 83c17c1c84cc7578008815746ef550fe11f57ea3b62801fb0f624b2c9c76e886578ec10cdb6dc5139db5dc7d82409874d8067203c170995e24d8b6b985116dfc 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: . ```raw 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/](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](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. Package: zenoh-plugin-mqtt Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6889 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-mqtt_1.3.4_armhf.deb Size: 1644696 MD5sum: 0dba6206df75f49c45dfcee7af4ce3dd SHA1: 3d4be9fd042ed6a854dc220430afe0d582f89828 SHA256: 66c449cbce337568488ff71bc2e0bddfed8fdf6049606b5b64e5a102eee42357 SHA512: 40166996b5ef7a5013d49f465c883757c5df48f44a6537e28c641bd226a11daeb2b7f0d13af49b2c4a6d704d9c7e52f5089f3ebe419f9b9b4e1b1bf810e3cd87 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: . ```raw 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/](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](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. Package: zenoh-plugin-remote-api Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9781 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-remote-api_1.3.4_amd64.deb Size: 2466872 MD5sum: c4e13fba399247602bb56c75baf3fb0b SHA1: 4531fef71e3dafa2553c7578213f7421f98754d8 SHA256: 5947862421e355fdc366648c241e30e666b86c17848b4e7decb3113012984c33 SHA512: 9c1510c687e10c7befab843b476d113a64caafb6db1daa703ff132904ab6ad847cc80b354f547f01a6a3ffcf2fc7283713ded9d5c77da305609b209d9cde984d Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9793 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-remote-api_1.3.4_arm64.deb Size: 2291272 MD5sum: 7b40083b2a6c7725edb749678df2c6ab SHA1: 79eb774c5c933ce6e4234a660906d083709e65db SHA256: f283852d85e8f57e9bba1d62c96125b2fb5bf7c986af2768207da00c16ec0be3 SHA512: 8f4865fdaac8e474c9d3eea1b3c21d95ed78c40931de3e38e0b657f5cfb462e071011ad0f0a4d3ab99bef54650be41d98c59f9407e972caa2e04888c5858c490 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8829 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-remote-api_1.3.4_armel.deb Size: 2064860 MD5sum: 72e1dd86af084c27d57da9ee097a3f25 SHA1: b5e94c3cecabc1d35c57934cd34443aaab4655a8 SHA256: 2c346b4a9e290dac1b880f986572532849c8dce46131ba44cc1b08ec5d1aca34 SHA512: fc75e797e8e40edc582547582de22a7c322eb7b8ca6098020947add5827ae70045bbe49fdd4662243dc96641d22ef7bf80e241de7d8fd1b76712e70874ad8992 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8657 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-remote-api_1.3.4_armhf.deb Size: 2075036 MD5sum: 83412f923f6f80257ef6a0eb6547055f SHA1: 9dd22df13c0e26e0cd7e5411cef9c53c547fa128 SHA256: 93cc4a9f6ad89b0e27c115d2cea8b9eedd85b5c34d1b17a1e2e2ee375eb9eb99 SHA512: 3a0ef30e841f6e5c9ba99eb8b87db904d8936d709ce6c9c17a0e79e740b9baa5321a6d18b0a76270b3e2fcff3452eab915b015201bc5faba852283d3ee0bb2cd Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-rest Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4602 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-rest_1.3.4_amd64.deb Size: 1239764 MD5sum: b876a20d2092ae063de6b7e05bbd6d7d SHA1: f23974446dbc28a170808ff7221faaeec5f62f8c SHA256: bd57c3aa55a1ecd99ff686519a73d9d28785379795f02c68c5b7cd024a8b75af SHA512: 12c6651691b34754c18743de52fa5d1b0e2ea98c64d775858b7995d633b774fb10040c86cac242fe71969afb7acfe767a20abb66a0e96ad9ff4daa67596225c9 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4652 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-rest_1.3.4_arm64.deb Size: 1146952 MD5sum: 4ded8c3ead2d562a7eaac0c8c0407b99 SHA1: 29935a5215954fcd66f6ebb418805953672649e4 SHA256: 13c4369517d0cbef5d71b27f840f8e286c7cb6c09b59615d6c88dd009276706e SHA512: 429e5f7c9fc881d63c8a6fefcf107e7e035154ae0f9a3fd037355d51bb1e91161cd5d49045192193e187a0877a15413cde00a06f8573111a4dc0ed43c5e13681 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4382 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-rest_1.3.4_armel.deb Size: 1185448 MD5sum: 215efb2e7c00e8ab86b769e85aacf96f SHA1: 5862abedace2dc523d53445eda9eec99f25b25f6 SHA256: 21bea1c8419f1fa58f93813e98c06d2d468a1725f13563821008209a4a9a53f0 SHA512: 4da85e4b57088b068857d336d5b260dd41a6052e90b91ab2e82654140dc6e7656d40ddc98bdb0cf6a089b5ff9bcab6e07b1686bd46886d40e27be06f5a6c6e2c Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4309 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-rest_1.3.4_armhf.deb Size: 1181888 MD5sum: ead115ef4efa6b02b1d0d949e381a509 SHA1: 9c443a86ffb08b66567099e093178623b2d7430e SHA256: 1e1cf8ce2dcd77a8b0eae6b117b5e0d562b1b592220892b3b71ee38943d2e536 SHA512: 73622392a631ef5e9ee42879905d09dbf0aa98716a468fcc7cbb20c134356a15999c2fce0e67e14aed756dbdbec80e64ffb565a366b41c9c6eb753b909b5cd5c Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6889 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-ros2dds_1.3.4_amd64.deb Size: 1811792 MD5sum: 16d8f01d3d9164c6e9750b716f96b38c SHA1: e2d5ccc999fd51e7518fa683bdb82dbf343e0a89 SHA256: afd2183cc513d301a732d2089920dda95e0c7864ada12e5a6272215f5e67281c SHA512: 8485ce836d41051abaf09e2e25c23a9ae4a3799f5f1585b4dda170387bb8fe86e97244392bff54befe00a7deaede3057c568853324101f4cc517ab7cbcc2dd18 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6747 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-ros2dds_1.3.4_arm64.deb Size: 1654368 MD5sum: e7bc45e38678652c40cfe5d6a9a04064 SHA1: e704061f2fd97e4e942f0945cd7cfac56e98c0bc SHA256: fd417fb442fd5e118970f5aefb745feb92d55f69a973bc5da6623c292f3bf7f5 SHA512: 048ce93afe232f558e2494368988e2d16a3d482b162c3e1b89bd43bf55444e4156c2065381a19b02d13b0a7b21b3550012c0a521287eb4fce60ba7f507f69a34 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6336 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-ros2dds_1.3.4_armel.deb Size: 1669956 MD5sum: 10f0dc21a5bfc810d8cf400a774ef269 SHA1: fa2b8c40a9deb282200fb47fe42a48efbde2d858 SHA256: 7acb2003e3b158491eafc86dcabd84701dd4a13bc6baff7baab4c9611c1689d6 SHA512: 9e014bb541a60d6f277d8a6669f108111f7640bc68a5ae978de9f7bb6a7ff888afcf382dc47768f07715f359b3047c41d57cd61fbc514bfe729f0e21586e1776 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6001 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-ros2dds_1.3.4_armhf.deb Size: 1691428 MD5sum: 80e0d08fae1cdde9bb8934ff778a2b85 SHA1: fcf45835d07333f9f5d1aec80f2ab1cccfe98c13 SHA256: 34f4ea2554c8ddeed4cc3935ba6693d690a5194fc6bc762ab4dbe90013f53502 SHA512: 777557f4c3a4d4641c8b5249c81608e63f2d2998fb83b2494141c7a5dcb90026ee9dd4b0f1b8b80ea57532d5f1ae5696faa3d911e14ea5a88d996f2563200ea3 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 described 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/](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](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 maintaining 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4341 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-storage-manager_1.3.4_amd64.deb Size: 1132536 MD5sum: 8f135cd97f4858b690695355794d6ad4 SHA1: d39ca9d3e1b9c6dbc131a604304c6a855af8ec88 SHA256: 633df3e27a80b8463f0bfd408d3d1f0987fa58bbcfe879810d48afa125b34f5f SHA512: 7032af5a6ef1daced705cb825783c9202f4a7be139313deb15e090919dc19b2f0b7d451e2659e401b36a1d334ef351046dd0fd74415008481a63cdf7ebd92204 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4369 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-storage-manager_1.3.4_arm64.deb Size: 1048788 MD5sum: 9c178e77f47c8b046bc1c35c67fd78bf SHA1: f15c8a7a2012c6d90175ef01597e6e6b2d3cb161 SHA256: b19273fcae761599537bb82916c34bf1a679f917eccbd54b5c7026cac8947dab SHA512: bf6d229dcfff85b5a28d74b9122b7faa8119d08485d45b714ce74ec804edf4a5d62cad99f407850359a3af21df39083b09313d9ea1816dc6b5f9a01117cc21f8 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4127 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-storage-manager_1.3.4_armel.deb Size: 1099056 MD5sum: 4edadbf9d72dd256f401fed83df9d7e9 SHA1: ae154b757290f45ca68960e2d1f98741d67e6c9a SHA256: 8690ff1ba529fc99467fd9951ef0ead54d59c8c07742f909f4ca43350397a069 SHA512: fbd2c5fd63f0bbd9c7feb8d49c11361cd156712c6fc8351acb0d667ceb09848ddd074d01f00e8f23a9176792da375125fd9e424dc365b23a51da82bba34a7639 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4039 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-storage-manager_1.3.4_armhf.deb Size: 1095484 MD5sum: a195a08d0a97b62dbb6326586ca4316a SHA1: 953f30b8e8f9cb4ec427ee22e277228fd2a41255 SHA256: dd8729ca9aeea9991dc45f9a5f64f5bfe4a7e7f1a0e50a5a4d5f30c0cef02dc8 SHA512: 1bce0afb320f9e8f7df6146d70d88cfc215826c1c3ac087f5cdc82106c9e68f0523a95b406b341d6f077736a9ebed1085d49e01daf9c34856ac3e69b23f8987a Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-webserver Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6952 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-webserver_1.3.4_amd64.deb Size: 1653768 MD5sum: 6665433084186bb9adb431ba08b71579 SHA1: 3b8fcfc2704315531f94ce79719702d1768be286 SHA256: 3e1d0dc6a9cc702325c3cad68e9644da402ca36b753d7fa585c314c3e6e1f734 SHA512: a01efdf6f3b8383d3ca8fd4b4bbe62bf15250c848e2ff45ed98cedb2138b2cd30e5166ea668e39abed280aa767817a12f9f7baef86def693a0499f4ce5536c49 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7189 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-webserver_1.3.4_arm64.deb Size: 1554980 MD5sum: 5a828dabf39e392c16c64b4e1588b27b SHA1: 36a6d4b5b929902ec5a1aefa2aa9c47592f58eee SHA256: 2409af5dbae1f3f2a0798ff1093522d2df225ca423787968cc8295be7f8f9d3b SHA512: 8e8292b12a4c6e99f142c55c58881d753d81565c64ff9a5f9a4e335e6a6b7a737390b5ed398fd759ea1e4c96a71df95323016000ff11a91ae5cde0e4035d0114 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6501 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-webserver_1.3.4_armel.deb Size: 1527304 MD5sum: 356f39d68c9c2b24f9fda76ab2eec9ff SHA1: 452b0b91b3ffe1f82fb2b256ec1e0a54e203a4e2 SHA256: 80be98cfc5ff88c642382edbdf690ee60d0731fde4e38cd3b97e41fdd570fc6b SHA512: d88df1c207b25ca11abbc573213312bc67e26407373bb49b9fd98e04059a3546b758f7c835309cb8d56319f48b5a89bd33f6256e12b4c538ffcef73adda3c9b0 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh-plugin-webserver Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6396 Depends: zenohd (=1.3.4) Filename: ./1.3.4/zenoh-plugin-webserver_1.3.4_armhf.deb Size: 1524896 MD5sum: df606fbea9308a350343ec0b63f547d5 SHA1: 9df48153cbe5578b6377d642392b2c4d056c0d38 SHA256: a75b011b17cf1d5bdaa0f2046444ba6ba7188d24f01f0c45c19ac29c0fe723af SHA512: b76df02bb6bf726524957bbe341e59f2e8e07518acf84776af4fb0fa0a91b5ed12ac0ea6bef97fe2aeb4d22c8374b43d014def6fd397278e06375cabb697fc43 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/](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](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: . ```raw [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: . ```raw [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 ``` Package: zenoh Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.4), zenoh-plugin-storage-manager (=1.3.4), zenohd (=1.3.4) Filename: ./1.3.4/zenoh_1.3.4_amd64.deb Size: 17556 MD5sum: 275ae380dc457dfcaa33a2a4914c020f SHA1: ded62839301ec9fe3ce7747ce1916946d2eca3c3 SHA256: 8f886f59db13fe6d1aa638d78565a9af995fe019f15bbad2735c2e358e5713a5 SHA512: 91ac5847d8c16f1586b681ed3aff153c6322445ad0acd7834ad09146ae3df1d602e554f1f89b8d220e579fb8b272a62847bb011ae7f3861f8c5057c4ab65899a Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.4), zenoh-plugin-storage-manager (=1.3.4), zenohd (=1.3.4) Filename: ./1.3.4/zenoh_1.3.4_arm64.deb Size: 17556 MD5sum: 945a2a763b6b8f5e1eaff64e575b4498 SHA1: db08dd566e28168d57c3d3a25a10c5527828537e SHA256: beee2f89a6602750803fdb56495f2d093c562d3f044e707a609efc0cdd0b3903 SHA512: db1f6e98ae4023e1f8e4f25062c5720d9564ec0ec0f4176ad7a86a4855d424461f1b7ca8b37c5dd4f6ad1a702d6ae7894f2240b50d7bd360f8c39d8925307d36 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.4), zenoh-plugin-storage-manager (=1.3.4), zenohd (=1.3.4) Filename: ./1.3.4/zenoh_1.3.4_armel.deb Size: 17556 MD5sum: 3cbc320b4a92f2af8c6b319a7f4f0e5d SHA1: 6a0be187bd8e92e256e246e01bbdd9a0e40ba49c SHA256: 251915df172219926314d387aae456a2f2d691efa5bfe1940f79d6b3fc28cd4a SHA512: a5be2fd231c46b2eddeb2a62596c632079de5c3f2b6d1668f8918b47cb6a6b003092eaf217d3dd60b439f4f0d823e665f063a70c9e566e16c98e8b21a27cdcef Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 41 Depends: zenoh-plugin-rest (=1.3.4), zenoh-plugin-storage-manager (=1.3.4), zenohd (=1.3.4) Filename: ./1.3.4/zenoh_1.3.4_armhf.deb Size: 17552 MD5sum: 64870924434b7edc617c15140bac2eec SHA1: 62cccd9f55354c095d4612c1a41b6c895b88784b SHA256: bc213c60a1cbab6e554ff43f248483e151ad3098e61c7161f1f273d58853c8dd SHA512: fcdee0a9516897be0bb1ade0bb55eb25302e2a552d91f247958fd7db9c96407fa911200ad0fe1de2aa4d848c38cdc9f1ac8fe1e4aade34f0e5770deed621e25e Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: amd64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13972 Depends: libc6 (>= 2.34) Filename: ./1.3.4/zenohd_1.3.4_amd64.deb Size: 3885596 MD5sum: 9c538397c12a0a8edd634ab97abe18c8 SHA1: efbcb6aefe2565e246f5d300ddfda1c3742447ec SHA256: a7bb17e381d069aaf0ff7ee47c02485f7234f68e8c98d128072616bd5351047f SHA512: 3617bf594b234d5d3f954eadc7965491c87039ee301356256217d6367d6db491a578c1d3a83004787e45d9db2e4c53003911b6a81ce6577982aa521b1643cd9c Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: arm64 Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12633 Depends: Filename: ./1.3.4/zenohd_1.3.4_arm64.deb Size: 3467564 MD5sum: 6208f9841026c05ed389111ad69467cc SHA1: d9dec784ef339dd0d6895441ee20b6176ba359aa SHA256: 3bbda156bba71aff71959a05999d48f1f09b87423c9e22578539eaa81096da46 SHA512: 5a97db83e99016d93cfad307b31497368088a293b6d025d362d85bfb7551cfe18f7e8cb24b3c67faa02f30e669c1afb3654870559dccfcde04fd6434906fb3d1 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armel Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13293 Depends: Filename: ./1.3.4/zenohd_1.3.4_armel.deb Size: 3634160 MD5sum: f21567b98e9f36c693bdf917724291d2 SHA1: 8f76fcc7311202b4266165e4947f7fa4a4214d67 SHA256: 8506b0d9357c6767732e27f9e58516be29b85699df3afede8c65218108f306e6 SHA512: a5e576813b00af7275a2cb3684b87ce7e686a04f47a0ab966b19450cf2e343e9117bf36210c28ab86c3cc5deb78123b88c70cca39bee522fb4ceefbe9dc26825 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armhf Version: 1.3.4 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13021 Depends: Filename: ./1.3.4/zenohd_1.3.4_armhf.deb Size: 3653348 MD5sum: 5672435dc89b04312edfddaa3b56fc2c SHA1: 1e0c5aec4a17047b4a5e9be26c02eeed99bf9ec0 SHA256: bc12e3c9f7dfc0a2d0f057d2c6d9e2f8d38040a24aeaa78d00df615d238a1991 SHA512: ceba1cdc0df4b20bd36a794918bb62a40a4708b6991771cf2f69a992ec47273b207c2aae258a4735f8e2a8f8e1d0667aaac8008041bc583a7fdf2ed0037c0e30 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## 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 maintaining 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 successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: libzenohc-armv7-dev Architecture: armhf Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 30862 Depends: libzenohc-armv7 (=1.4.0) Filename: ./1.4.0/libzenohc-armv7-dev_1.4.0_armhf.deb Size: 9602346 MD5sum: 98b118ea4a3158bce35ccdddbb51fc00 SHA1: 4452d6d7fc0848ed3d95befce19a5b6294f94420 SHA256: f2d87e2194f068914c0f4557efa7b4179430dd05868bb78d4dd9e3f33ef3d4ab SHA512: a34849a1ea473adef8d324214cd5ded947de5a6a4402c8683b095fa29096a500733944aa2fb4a15fd5a7595392446db5459bfb1a8028d17058e9e125e7a2d854 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-armv7 Architecture: armhf Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13558 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohc-armv7_1.4.0_armhf.deb Size: 5734872 MD5sum: c414ad7119a81345bbab69a2c64790b7 SHA1: fdcc881168b7498f8f292d2a751d08c4994324a8 SHA256: 0c0f1a3c01f8524deb457979cc5665e03c77e82184ea72140863815c74b58f5c SHA512: c43c45c92c3ee1cf987a72e1c69ee5bcd3fb8256141ec313cc084c03ef5fb6ae3f70e0dfd77ceb278ba6ecaf74f3bf9df45253e97bdcab437839a95c4cc0c184 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-dev Architecture: amd64 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 37466 Depends: libzenohc (=1.4.0) Filename: ./1.4.0/libzenohc-dev_1.4.0_amd64.deb Size: 9207434 MD5sum: 3acd46b3039d9e2d8b46eb6ca3991823 SHA1: 5f27a0354e8c39c55aaf847dc4d32836a2f9b48c SHA256: 60084e6c8e670e663bb6a0923bb6c454175fd36bad4cb0bbc517c450066ff6d8 SHA512: bd5d8fbd431e1874ebd7ca85bbe8e9828c0a37a8201fcf12e9c10646260348afb0da30ca8c8e12810e1c24a54684c423864d73bd56a9709e7e7a5ac930b95a3f Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: arm64 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 36760 Depends: libzenohc (=1.4.0) Filename: ./1.4.0/libzenohc-dev_1.4.0_arm64.deb Size: 8872598 MD5sum: 75d08cdcb219eda0908ba84a2a2cd5df SHA1: bffced45e61dfd56dc7364b142cdfa9ba748c693 SHA256: fcf55eb0e4883147095d5bf9e2136f1f9845be6808255251eda12ad1eb0c89b4 SHA512: 4dafabc99f3a73635eef98d43cf728f67fa04ad56809d64ac72d5161f3dffd0d20db313c01cd8c36b415eafb77bb5c33e89257d0a409e9edd4dc01ee33232d2d Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armel Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31041 Depends: libzenohc (=1.4.0) Filename: ./1.4.0/libzenohc-dev_1.4.0_armel.deb Size: 9661146 MD5sum: d8fe341381bc6f2c231b1c06c38cb456 SHA1: 1760da54c46c30d0e3756871b094cbec43999736 SHA256: 2f420fcd99da1ec77709307e850e1ff3b8a52c36c71187e7ddc1ccf6ac8aa756 SHA512: c58c1e39c3f7e28287ea1583468d23779ac40cf737d7d9444fac69136a01ff71e1544a6d827d6cfee65205de02e71a846e463e05cd8b0b010ada34e2ba9f5e39 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-dev Architecture: armhf Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 31187 Depends: libzenohc (=1.4.0) Filename: ./1.4.0/libzenohc-dev_1.4.0_armhf.deb Size: 9783068 MD5sum: 41b11bc288a014ac649e61981018d1b6 SHA1: ddd04573942b59a14d268dc0786a620823a533f3 SHA256: 75a2bc663a08d1cfab146b763722a4fdca98139737dd455751a240ef58439dd4 SHA512: 7d0a9d7dd7669ddceacd36f287b16eeaa7c6a5379eb75023c035fcadc8d15e13a634798c62f02832265bbfa6764331f762e1df8ef91d2d9b8e66b9ddbcdb56c0 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: amd64 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 35242 Depends: libzenohc-musl (=1.4.0) Filename: ./1.4.0/libzenohc-musl-dev_1.4.0_amd64.deb Size: 9082494 MD5sum: f2cd4f439f6d95f58397dfe44b4c9060 SHA1: 855f14d673f91b21806d7d570be3e74eccfbd0bd SHA256: 61d43bccac0063345c8ca55765839843f15b8f53e2a6d37be0208de75fc0592e SHA512: c7b5fcc10503dd7812ca8eb888c6102e343e33b60f8dd7dfd3260fbf9145295f95ab334a92a936aa87c1790c8928b0ed143720cb1fd9e2188a5aacdc6af63122 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl-dev Architecture: arm64 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 36068 Depends: libzenohc-musl (=1.4.0) Filename: ./1.4.0/libzenohc-musl-dev_1.4.0_arm64.deb Size: 8736358 MD5sum: 8c8e2cf7f416810811f701e2ae432793 SHA1: a91858d146a0e717b285968e7772b1d161a60573 SHA256: ae77b7d1cc22c8d93afeb67141c1df462e9b16c8c6459f5fdb3111f948651698 SHA512: 2fae3afbfec34eab9e4eb4eba8d65b468108e574af5f8f081f18436f3b9190f9fa3504b3fbf202f9ccc944e6dd1e6e59ba9ee325e1853f274d39df19420a569f Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh - zenoh-c static lib and cmake files Package: libzenohc-musl Architecture: amd64 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 14420 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohc-musl_1.4.0_amd64.deb Size: 5745032 MD5sum: f1c1241175e35652ea54c3c162f8bba5 SHA1: df44def67b99b54591a0f385b44762b86cab77fe SHA256: ad826ecc998e7f87cc7841fc06d93e71b7901b921b56933332689e0bd1bf99d6 SHA512: 024163b7138a323e9ec924cb37b02699093c0e3381599193f7dc99eae2e4405b042d54d8421c665d6a4183e956b523177f61b95ccf866772668427b07904b31f Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc-musl Architecture: arm64 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13423 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohc-musl_1.4.0_arm64.deb Size: 5459458 MD5sum: 7e741202f65e7b0b6c9727702769b5b3 SHA1: 0a5d711df6de6f5ebb18633891c0e7037297745e SHA256: 240841ec3bc0cd2c745e1b433533d4a5b570349571e9c0352f0c9867ff7b626f SHA512: 6a4878a03f7ccfca83e7383aeaeda03ad2b5f6e1379189b3b9623290e66b6ae06306b356bc9316ba7061083774dd61749cc9e1eddd46fc1ea63d60c58ed284ab Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: amd64 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 14426 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohc_1.4.0_amd64.deb Size: 5745012 MD5sum: ae98aec619befe1df0aa40d58026f2f7 SHA1: e5ede9725ffd7751de82e02a25979b5d3e51307d SHA256: a4a1b19ec3c1f359ca6d216583bc55325ba42d4a9dcc0bcc9916fb4c0af3e33e SHA512: 5fb083b5ae8163e2dfe465230128ce635dafdb1d3a14855f7ff671a5ecac3754853e6f7f61fcc21a2fdb4dce09d0f4ef575f58a0dc29ff8673eec7e54b7ac017 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: arm64 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13425 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohc_1.4.0_arm64.deb Size: 5484568 MD5sum: 33ba081fe8d98ce1b68d482cd33b2760 SHA1: 29b94a03ca97bcf9b90fe1d7c04ed20e88afe01c SHA256: 8dcedeb011b9e014728d8ed7b4755763254b8ef41a73af318cd969cb87aa3c8a SHA512: c051f9c2344d58cce50ea8783f1eab4cdd65c4758278f9c953607f76e7f6df4ab0b6dd018a04137b82fed8889a1863531bda79968695b3b2636662ac0322f146 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armel Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13805 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohc_1.4.0_armel.deb Size: 5798110 MD5sum: 3a221886bc06711a8ef6dd26543059a2 SHA1: 358e8b34718fc03221079b49942e449e4c23d938 SHA256: 70bc7e4b11d75ea16042b3bf4e81b748fdc47454c5716fc426cc6e290ccf6af8 SHA512: 00bab0dbcc56420f1cdf7d4a05717b50bfe60d07a581188c3f81f68c7bfb428a08945577a346eaee3a8def77c05a93643ae35feb03f8888ffa5775dce9691c89 Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohc Architecture: armhf Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 13813 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohc_1.4.0_armhf.deb Size: 5875416 MD5sum: 0911b67d72755611fd1fc31c92538953 SHA1: e83b8841b0b174673668d5c3265871c9f9cb21cf SHA256: 9e2ce955769fe1ce05df40dc700aba54a59c6d50af32e660477e675b0f8b761a SHA512: b3939be06a59112db84f2c455a20b4933ff36da343e47ab37c88419ecc82b88fac1f90ed8f04b607a7b34a5c8df5090f1049d77409ca0cf29f9d55e4ce4be4fd Homepage: https://github.com/eclipse-zenoh/zenoh-c Description: The C bindings for Zenoh The C client library for Eclipse zenoh Package: libzenohcpp-dev Architecture: all Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 451 Filename: ./1.4.0/libzenohcpp-dev_1.4.0_all.deb Size: 57990 MD5sum: 8ce19abab74882e78114087e1b4dc5f2 SHA1: 973006d75b5c2ef426b3bcf0a341a0062b354028 SHA256: 85de6642e8dc04a3c87a8238c17a69d66e23e6a15d74d7cd7d6a16e588a845ae SHA512: f18b981c93762bb0ac45300e3f22ec4d279ca87a30a39a51a5dff45030c3d1d9693feb380cafe8a631f478632b3595634872e64a1ada994d01bcc3f42e89b7b4 Homepage: https://github.com/eclipse-zenoh/zenoh-cpp Description: C++ bindings for Zenoh Package: libzenohpico-armv6-dev Architecture: arm Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1265 Depends: libzenohpico-armv6 (=1.4.0) Filename: ./1.4.0/libzenohpico-armv6-dev_1.4.0_arm.deb Size: 254406 MD5sum: f0cb79e1c11159d0e82cd42852784392 SHA1: b3917dd6b3ee808a694b73fbacf1d1c415ef29b8 SHA256: 04cef61cf6068566c74653c112372ce43c27fd1ed75dee08ce79fd5afa0fe6ac SHA512: 03e564e55997b5fee953813f22fa00c17f222e6c93e6ef2fd5aa8b809515abab296152fcaf9dc9be0222a0cc49b9a9bf590c303d882bf363c4a237977acce9d3 Description: - config files Package: libzenohpico-armv6 Architecture: arm Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 369 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohpico-armv6_1.4.0_arm.deb Size: 151308 MD5sum: a35747d1e350e5448e11622a0c2c6bb0 SHA1: 3191ea02f4bab20af148db26583bcc1545fd846f SHA256: 411808192da356941d2d7f94fca6a28c3464d5694c7338e52ce54efe93b7eb43 SHA512: 4ce72acff2f44fa8995f95ba318602c6cc16484f1d8abe1e673e2bbfd7e2e0c6eaf26f74984e59ed6caea8a551bee4a2048f8af5f1d9109b994c7b9a0e391fb2 Description: zenohpico built using CMake Package: libzenohpico-armv7a-dev Architecture: armhf Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1257 Depends: libzenohpico-armv7a (=1.4.0) Filename: ./1.4.0/libzenohpico-armv7a-dev_1.4.0_armhf.deb Size: 252654 MD5sum: 7b39eddb84890e78e18a66d5ffcc6eb4 SHA1: f0c0647944ade2f559d2ae27855744538c02d214 SHA256: f11abdcea6e12221d1cf8fe7e410a4b4801beef425948e061fd017e13287967c SHA512: 733601ed97844cadfaf07912a5c7731e162419869cd25d171b0218fc85917bfcd410cdda47fdc276360dded4f4fe49a2ac252aab19f89ce0726707c42ebb69cc Description: - config files Package: libzenohpico-armv7a Architecture: armhf Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 365 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohpico-armv7a_1.4.0_armhf.deb Size: 150460 MD5sum: b2db72be0a45cbf5a609d6fc22f9dee6 SHA1: 02818899ad2d68d5d81a2b1cc3ecb214c362518b SHA256: 1853f4a24b9ab74b34a544e80a8df5e0cd957741901a939ba0c38767354438b0 SHA512: 41240ad9d86fe52fbec38443d4964a6f98e12e5d2b99daf934896d14059e0112fb35b00fde96b2a76b54dab3f0e29066fca9aba247d863a966d5d02b7ced9492 Description: zenohpico built using CMake Package: libzenohpico-dev Architecture: amd64 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1520 Depends: libzenohpico (=1.4.0) Filename: ./1.4.0/libzenohpico-dev_1.4.0_amd64.deb Size: 302836 MD5sum: 82ab0f19c57d21c3e5b0a57b7d271c4c SHA1: 62fac0227a4a836391773c5458849672aa0443b3 SHA256: 87268446a95e0eb31b19b8d4dfd88a77dba8cca0bebb27dab28d793af2cb00a4 SHA512: 2ea7fd51e965d674f3042722da55329c993fe603675eea4d4d0bda82bfddfe77d5a515dfa75e3465b5e7715a9b116fe7414efbd150607a72d559845f7625eb67 Description: - config files Package: libzenohpico-dev Architecture: arm Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1264 Depends: libzenohpico (=1.4.0) Filename: ./1.4.0/libzenohpico-dev_1.4.0_arm.deb Size: 253930 MD5sum: e55f55145a0ee6c9f03b109933553179 SHA1: 087a8c819e9fae28c383d35100755e9fa1d3ccb6 SHA256: 65a42e238c48980d86d6b3558736bd0408c8d71de49fda437b28e99de3b9ab7b SHA512: a383c8e59f62483d78baa90a20f69b8c6c05ff0d2167e66e4a728c7eb43d46f1f1c0b25ec8558e5746d7dffb7055f20c50f7bfbad16c42ae4dbbac1b8aab6f31 Description: - config files Package: libzenohpico-dev Architecture: arm64 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1531 Depends: libzenohpico (=1.4.0) Filename: ./1.4.0/libzenohpico-dev_1.4.0_arm64.deb Size: 299052 MD5sum: 47b6e973df00e063909e411df84f2476 SHA1: c8a15e158205961a0ef489d1008e72f2839004bb SHA256: 9e19f4214011ea2c4dc3a0b1bd0b989b74c3f9e9577744fec5a454e45a1ac8f2 SHA512: b21803f0cf4b123a3bcd9e0c5dd9c9daa3e447e30a72a9a9ee2a98fdeabf4ad9f00d7d713d9e491bbcabc392dbf7638fadc99ba90c8d04f1ee777b36038a6338 Description: - config files Package: libzenohpico-dev Architecture: armhf Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1258 Depends: libzenohpico (=1.4.0) Filename: ./1.4.0/libzenohpico-dev_1.4.0_armhf.deb Size: 252352 MD5sum: d92fc692cd78a25430bce6633ff05a9d SHA1: 7317b6d0254c864fe89159007883aed2171ca5c0 SHA256: 753a3780353364950c0257d0bb7c8fb612c6300ba1680344a624ee8d14eabde1 SHA512: f401068801bf91c3ea1bb2f53ef9853cc61c6f01322d3e3090106c79067aef69e91b7eb9b9c2c0f3dab02492da006f85d1d72964aa38e7c7d32e6a1d760018ee Description: - config files Package: libzenohpico-dev Architecture: i386 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1492 Depends: libzenohpico (=1.4.0) Filename: ./1.4.0/libzenohpico-dev_1.4.0_i386.deb Size: 331060 MD5sum: 45b1f5fd18010834f6af11e1c323aea3 SHA1: 7a29330aeffe0b691d047550a0e818d495034b59 SHA256: 27454bf24679557aa032c528de911a13b9572cdc3ab159439f000ff1a18b81d6 SHA512: 5084ccb9ac7e6f2f48f88f1257c12550c86491dff25c21342637ea08a60071da323b450305ea6b96c5a21e293cf753e3ca8b14cdc801751c0193294a8c9ca59d Description: - config files Package: libzenohpico-dev Architecture: mips Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 1414 Depends: libzenohpico (=1.4.0) Filename: ./1.4.0/libzenohpico-dev_1.4.0_mips.deb Size: 287970 MD5sum: dff9e48f3d3f5310b7652ae2a93c3179 SHA1: fcf379fe56070437b9d76e62494b356e04482084 SHA256: 6631ecfc04950d80ab67c2a6d281dc523531bbf451ad840503a67d0833a33bb5 SHA512: c71a41e0bb4a91cb746d7668fcdead37094fa1df28554112a10d3699963f80f4463d973342ad0a86d5e164a1c92ce3094afd06c6c887d861c186e57a61bd9290 Description: - config files Package: libzenohpico Architecture: amd64 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 496 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohpico_1.4.0_amd64.deb Size: 185068 MD5sum: 59efed7b9d3444f970e673f817e29c03 SHA1: 6d531fd6c8414268c2d122d645a1c01daf7208c3 SHA256: 1e19b8d9ddfea0cf91d1a0e9276ec528d069c174eafd59a59d4e778b0da63b0a SHA512: 66bf9d3711a4859f5f60cd4fe0c848bf8db3032f6beae91f74a5bc89b9cd943c34de1912cef17c81cbbe9453cd62c640a84866be7add23a5327e368b243cbc35 Description: zenohpico built using CMake Package: libzenohpico Architecture: arm Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 392 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohpico_1.4.0_arm.deb Size: 159296 MD5sum: 74b01ed588fcf85278bfc7bf82cc12e7 SHA1: 7c19d1113c3d05c7d3807e94577bd82f0b04370d SHA256: 4b9f66d4ee2c8ad2a04e029d51e297ebe3574926d92a55a2b39f0030941d3a2b SHA512: 04b3c01f0948e28708b6ef098cda4b45de5d32a7a460ec2b3b4e174a272aabeb32d6a4c8b64a57f0ab555d1901a4609afbeff38ab14df24729eb929c1be5b61c Description: zenohpico built using CMake Package: libzenohpico Architecture: arm64 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 510 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohpico_1.4.0_arm64.deb Size: 180360 MD5sum: 32a80c4ed552d26d6f4e4fd79f2f4429 SHA1: 513e70f13b564bb11af6e5225c6e543cc8e37d50 SHA256: 3b250d77c951dfba6f69c578cf2787f6aad25502553c89fa6f00d82194f4126c SHA512: 6f335462e146ffc09b6b5ce9041018c9e879715ff0993aa2bd5f7124b1505d57836f2e0eafecdb2a8c07067d105eab2bf5a7408372deb9af54a737b607d0aba7 Description: zenohpico built using CMake Package: libzenohpico Architecture: armhf Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 367 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohpico_1.4.0_armhf.deb Size: 151492 MD5sum: 4b735fc99a6efd49bd7152230b878136 SHA1: e4f94bc491a6b89d1218b84539b4b0c93c5b61ab SHA256: eb35c96ac8ac8331ddc518dde5cb67a3cb09dc8fa11f7590a842e4d823928e54 SHA512: 247438d1fc42a043dbea538856b9c7d881e731f0d6804e4d12e479c3ae08723a1ac38020dc2b0d068ffcab342639e0d7294728743f3a5b3f28df02f5a341d887 Description: zenohpico built using CMake Package: libzenohpico Architecture: i386 Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 534 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohpico_1.4.0_i386.deb Size: 212104 MD5sum: 1ee27a34b5e8b8b2630ed371b415b4e9 SHA1: b6569fb4192211fa9fb7d40883a37c428e094615 SHA256: 24ccf43f7f3861eabfe041ee2744aa1f1a2e9dc1c753ec70106c4e4cd58e70fe SHA512: ad33ac7a3a498054aea37c76e89c48be9dc9fffe4788fd294719c79397e76d475b508c6c18492f27b72d42c258ee5c1365af96266286216ff816b10b55d526b6 Description: zenohpico built using CMake Package: libzenohpico Architecture: mips Version: 1.4.0 Priority: optional Section: devel Maintainer: ZettaScale Zenoh Team, Installed-Size: 480 Depends: libc6 (>=2.12) Filename: ./1.4.0/libzenohpico_1.4.0_mips.deb Size: 166432 MD5sum: 4a46a63b31245ce8d4f1ff3300421217 SHA1: 2efebf6481c06ee8606e55cea918aa784f199f56 SHA256: f3be44a5dbd49c1a72a45b0049cb017abd49f0447e1f40f7af26830d360a51bd SHA512: 7d34ec8427e2683dd3c746632e3f73399565d7177808ae5be60c4a96d841e59384b7002620ad35ab187162efcb992bcfef076718defeba930e4848f1709b20b8 Description: zenohpico built using CMake Package: zenoh-backend-filesystem Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15520 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-filesystem_1.4.0_amd64.deb Size: 3986704 MD5sum: 353c29f39bf69d663c1ed391e464e811 SHA1: 1e1ca71245c51fdc95e99da0f191dba288364edc SHA256: b875f6995580037fa17cc4e3d9aefc9301a24f96bb522fdb0c6a939172dce7a9 SHA512: e4fb47a38fd28699f9d4a7f2bbf95c29ed54a345c33ba91378ad7db114ac3c638e7d720ae79743540fb5c1955bcb893837f195b654f9b2fa950742b0b3cf86a7 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 . 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 ``` Package: zenoh-backend-filesystem Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14117 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-filesystem_1.4.0_arm64.deb Size: 3438708 MD5sum: aaa352a9b05e69f433b26558c5a6e2b3 SHA1: 6684b7a8f420dafb464b67d3d79da4ed93424f07 SHA256: fb6c2ce423f24a16f5f2845217e1e2dd2de000f896269d2f2ade111ebe10d1ee SHA512: 6b9bccf71ef127a6e1a33bb96f12fe69d9d21702604063ffd9896daf1b596b4fe087f9c841c0f75e2f4f6411a40453cf2e64e7d5136709765cca926e53a4afb6 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 . 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 ``` Package: zenoh-backend-filesystem Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13279 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-filesystem_1.4.0_armel.deb Size: 3390472 MD5sum: 0ecbd01c8a6ed47d60e15b559c5dd9d9 SHA1: d9223990e4e3b02f7a89f7508633b15dca4d4fc9 SHA256: c9b06a53af4c5969a62e1c7f1555a7a023e710d9e33df6b63ae73ff663fea891 SHA512: cd4eb8b333069d6d91190431fb73fc9f9b55b5187689aa70d4028dcf8ea7a815969d2603b2e0698aebe2cccd054e696741cbf25ff66f767c27c97475cecf1a13 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 . 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 ``` Package: zenoh-backend-filesystem Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 11240 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-filesystem_1.4.0_armhf.deb Size: 3503204 MD5sum: ae075e1d5f09f715255fa7b1ee15a807 SHA1: dbd3bc2a2263b3fbd1d83974863308bf70ec6f46 SHA256: 4ea738bda4cf2e3be212fb53e08a33c4bd39a88c89f7242ee1eacb4e4a10c96f SHA512: e8e4c176d35eb59ebb16cfa07186886e64e534cde03947a6a520219308371d5b2173bedd4af96ff7cb9bea7e07ab0a56ba12ce504b06ddab1c3966a4a0c0845a 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](https://zenoh.io/docs/manual/abstractions/#storage) 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 . 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 ``` Package: zenoh-backend-influxdb-v1 Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8056 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-influxdb-v1_1.4.0_amd64.deb Size: 2076180 MD5sum: b0bd2e8be24d2073bb3a71339291d436 SHA1: be14d7e68b2a5fda3002bdc210bd545594984ab3 SHA256: 365c7ba935d87fa29864d05c38b8b0dfe42df356fc64c3ad205cc1bfa55add66 SHA512: a3e546ef3740cc6bb4ef5170411d6e70dea9fa185e3cf0b3b1362db34c63d25b26e358c7a0b980ad419b059dad1ca6b9c067f81c08bf6caa3a89078438be0026 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8014 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-influxdb-v1_1.4.0_arm64.deb Size: 1896640 MD5sum: ffdbc29bb564fd20db9f03f59f9e9d06 SHA1: 97ed68f123d715460197844cb97de3be7dc9c872 SHA256: aa065ec688f91bc7122cd454f39e58f2d50ccfd4597fd43e005dd51fb3ef23bd SHA512: 28784e21ea5fcea2c72824aa0d57cfca83b7fee714ed5b570088a9b47d37ee553345b2563e63ef7140869cb3c1e9e8a4fd5cbfed59a9cd4df040134926a7d8f7 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7121 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-influxdb-v1_1.4.0_armel.deb Size: 1726576 MD5sum: 81009042d012895b575273ec80994535 SHA1: 54a544f519d56bdaa860790b03b7a1b1ecb7401c SHA256: 42101c4664787631c3aaa620d36bab438d2db3eaed4aacd7d4041fc8c9288b3e SHA512: 384eca411ad49b42f2aba5da7bb0655a762f5001b4db02fcb10ab201eca2b0720f9505a708f0e8fc37c751ff5882138fef8dada36fc9a6acae335db6edaf7ac6 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v1 Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7017 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-influxdb-v1_1.4.0_armhf.deb Size: 1723852 MD5sum: ae5d3047345b2d43acba57a528f24db5 SHA1: d511fd297388ed156e479f9b4fc26fe87e967302 SHA256: a19bd6223fc0402127e55f71c8c202fcb6e7926b1a6f5591782e460b96e6b3f8 SHA512: 694a4f287b1dcfb24d0e078bdc3f80dd5433635d4c50689c7faf8162f28e1574ad31f8efe2dfd1de5979d96ea82473693ae73d9457a609255255714a3da227cd 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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 level credentials . #### 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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10766 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-influxdb-v2_1.4.0_amd64.deb Size: 2792612 MD5sum: 4a383636d5c51a0b277a4554b2b3c9c0 SHA1: 93d4ca98bda4984609a1ebba739e04aa0348f5b5 SHA256: 77efa1ec76fd9bc5005e8de9b257403af4cb565c208eae13f9c5d2131212a20a SHA512: 78525f21d66193cd4a01be1902a29973ff7693d42a42110d42953cfd76847d3787f417d4a5bd69dfd0154eee281ee252d55b6f1a6c2d4960b71f752b2fb613e6 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10734 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-influxdb-v2_1.4.0_arm64.deb Size: 2600912 MD5sum: 34db5c7956f384742a4a5d5b7d4bea02 SHA1: b67061086f5e9f3d28f24a84dc547ca7a220a090 SHA256: 85f002b72d684ba92c98c55b1cd3245d42fbb5dea5796c5e6a86d7b6076e4fc5 SHA512: bfe45960a415f534424af808093e7674f7f5e39f0aed82ea7e8fbfad8a697d0277606e89eb19766e0cb72c8378b8354b6bbc79067ce9ca20e5223cf4c6396542 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9667 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-influxdb-v2_1.4.0_armel.deb Size: 2395812 MD5sum: 7ec848e88cc931ba6ecd8d12deae41c1 SHA1: 3d9c3b83bf3fa86760c0d2a61ad9532c54325db3 SHA256: 89edd24901519ea2565fdfac9fae78f3ad654a10e5a16fa220316c07c02a3f83 SHA512: 23c6cb6ea425e71527a24611d3f36212ca46fbdccee755708aa93cf1003e332b7a1352a4738c5862b318ce71d079582fa31b696247b882026b36b2cf24a48e9f 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-influxdb-v2 Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9523 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-influxdb-v2_1.4.0_armhf.deb Size: 2413668 MD5sum: 61269970249bae84cbf246799e6adfc2 SHA1: 7b8c80b5ee762024a447239fe074b907de9cf08d SHA256: b28ee354a7f836017a239040b813698f492d2fb357cef11048607fdc6297a3fb SHA512: 9a465011a3498687db51daa1a7610bdbc129138c6e971bad71264619f340e59e8c2e62e54bd3046ed948467aec6fcb915b83a37a9e5996e3b3a148fe350c7331 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - Add the "influxdb2" volume (the "zenoh_backend_fs" library will be loaded), connected to InfluxDB service on [http://localhost:8086](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](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/](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](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 ``` Package: zenoh-backend-rocksdb Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14472 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-rocksdb_1.4.0_amd64.deb Size: 3765620 MD5sum: 8ae1ee33d686d3682c19af3b5533d170 SHA1: 2fe80812b11283df29669dccdf5896391664b228 SHA256: 36eeb6723941f4a20ce2a93dc63a7052ecf4b522776af13f9278df09d1d7b166 SHA512: 47d9216096ff77712009ad97ef86e8eaada8188d9fb57835bf5ee9da101bf38ce80333d3823463297ddf2b4f1735e18df37f5f270997d655482b6f69ed132afd 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 . 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 ``` Package: zenoh-backend-rocksdb Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13054 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-rocksdb_1.4.0_arm64.deb Size: 3247652 MD5sum: 0df6a7c4bf18ee69df0a120038696925 SHA1: a442767614cd72615ecf774af431610cc6ba48ba SHA256: ceed6456b08886015fd1f815bf5772a4a7229fb317b120fee1445e37a7f8e038 SHA512: 97cbca974029e1170c15a4eb4c6ba2189959965b56dd7d1121c7e5500d376e1c0feff88168e551881df8ba935ca31ebf25421f2b6ec2f210ef917fb94cff6016 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 . 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 ``` Package: zenoh-backend-rocksdb Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 12432 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-rocksdb_1.4.0_armel.deb Size: 3216600 MD5sum: b018d623ef00d25a39bfe717f1620600 SHA1: 10ad83565388f3a4048beef8812e118b84dcdd83 SHA256: 28c6a86fb095225870aff188e0f8db8c0e5730d3c6e7ea86cb02c78c53a2ae96 SHA512: 81813d5c445a601a56939d9b8c1d8cef676da5bdc2aa2fb69d046e62bb04d8bc1c8f61f967c7fb9b244acfea71cbd9ea4fa5a179a723d724d8cda6db2bf10cd8 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 . 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 ``` Package: zenoh-backend-rocksdb Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 10357 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-rocksdb_1.4.0_armhf.deb Size: 3340296 MD5sum: 2909f7b35a2bbce14ddcfe8c61235c46 SHA1: 6265e1a1268be01faf24605a838f8a0b0c4e87a1 SHA256: 470fab46295033fa82cad14e710fa61ddc8dd4730cc8bad77d6995f29cd25425 SHA512: 20a79b832d9d067ab6caa2c7e017e552f02df2ebacdb6ed0177c316a7120914543e04cab20b49c49c893be526526d4947ffdb95947b47f175db31b691f0d835b 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 and with the REST plugin: `zenohd --adminspace-permissions=rw --rest-http-port=8000` - 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. ch 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/](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](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 . 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 ``` Package: zenoh-backend-s3 Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20360 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-s3_1.4.0_amd64.deb Size: 4430336 MD5sum: 3814cd26e8df6da4ed78bf88194825fe SHA1: e569f76b6e1435558871c657284f9e4c03608cd4 SHA256: a6719c4abbad762f43ede3540de0d12ad211afcb9510a8239f39f565d46240f1 SHA512: f12f72e6c1ad844f577c2e79a00d53eab6ff657fa84400771b5f7c042d4ece73f3d53ccbe7b84ce3dc0380ea3af785aa9ffce09f9d0c9460a2294411a5cc9150 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 . 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 ``` Package: zenoh-backend-s3 Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 20551 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-s3_1.4.0_arm64.deb Size: 4201148 MD5sum: 63bc2ada2784666a5ce70e34106d8087 SHA1: 91e7d781551e2e51174313d2edb7f379a4946a66 SHA256: dbe7cad0906f0477ba7f1210107fd00c3831a47e54fedd77e25dbd0ecf13e188 SHA512: 3efd447aac8da71fe752a14dd6a86e9ce5ed5613922d8221dfbbd304f8f541d618d9e29961181625d152526715961fd7d5b5190ff8e0938f2e7769fabfef2275 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 . 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 ``` Package: zenoh-backend-s3 Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18951 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-s3_1.4.0_armel.deb Size: 3907456 MD5sum: 88450756f7002eaebcf0c0fde51357e8 SHA1: b817c8961ad3f8df3b7607c48fb04e460cf5cbdf SHA256: d20833c76bedbcef1b0b0ed14a9bb44fd56630546cdf0746640e68e751a1c5e0 SHA512: f01ae562d038908675e4d85ac5f1197d70b1c1a4aa6206e246c7ded527d402921526ec96b65aa4f3df4f810034502ca45de40442ae86122e7e3b1c21ebece468 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 . 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 ``` Package: zenoh-backend-s3 Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 18700 Depends: zenoh-plugin-storage-manager (=1.4.0) Filename: ./1.4.0/zenoh-backend-s3_1.4.0_armhf.deb Size: 3937736 MD5sum: c9e5f414be4de5ddea2fbcb643daea09 SHA1: dcdc65f7b753b2ccd3e37e6aa8a96e0fcee49a2e SHA256: 323a0b0dd89275b15ff9833d50dd64a6a6adbb1c13dc15d166df08e33a2d4c7a SHA512: 2688988e21c41939244568c836431375348859133f6fc28f31c9e1db3e63bbcd0fc08b3b1e87141496ae2bcdfc67f286f8a832d36d4b101fcc183f63a5d507b2 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: . ```bash 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/](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 . ```bassh docker pull minio/minio ``` . And then you can use the following command to launch the instance: . ```bash 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](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: "", secret_key: "", }, }, }, }, }, // Optionally, add the REST plugin rest: { http_port: 8000 }, }, } ``` . - Run the zenoh router with: . ```bash 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: . ```json 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: . ```json storage_manager { volumes: { s3: { url: "http://localhost:9000", } }, ... } ``` . ### **Setup at runtime via `curl` commands on the admin space** . - Run the zenoh router: . ```bash cargo run --bin=zenohd ``` . - Add the "s3" backend (the "zenoh_backend_s3" library will be loaded): . ```bash 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: . ```bash 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 . ```bash minica --domains localhost ``` . a private key, a public certificate and a certificate authority certificate is generated: . ```raw └── 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: . ```json 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: . ```bash 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: . ```json 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/](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](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 . 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 ``` Package: zenoh-bridge-dds Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16222 Depends: libc6 (>= 2.38) Filename: ./1.4.0/zenoh-bridge-dds_1.4.0_amd64.deb Size: 4706052 MD5sum: d23f2698c178a24ae7702bb035e20673 SHA1: 58021439d3d8b64c33e113c3dbe1a8e75acfafa5 SHA256: 78d6fa7ed802260628b9ea7c3a5c188825eaa950cb0e4a48c3b562db42885559 SHA512: c7f3bc2a33f49f45ae05a54afd3be816aa1678b157f4dce175ede70afce5373a41fe1301b47746c05f7e870ead75fa5145a549baf969a2db2f921874947a85d6 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14977 Depends: Filename: ./1.4.0/zenoh-bridge-dds_1.4.0_arm64.deb Size: 4205892 MD5sum: 7759b7f5b9fe9ab154318dfbd4e7a439 SHA1: 098d186ba7f57fef5ac5d81039232b8e8f3cb22e SHA256: a0574d7c5adb31269cb6b7d807ba1c639ee204d5363a1c0f5b3f88432c1681af SHA512: e5bc9fe69df4ed45e424de27ec005efe58e661a425be313b9d716998ec0dd90cf331904c3ca6d1d7119162f7cfc279d893e7cb09ae2a85344d1868a8a8679abb Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15384 Depends: Filename: ./1.4.0/zenoh-bridge-dds_1.4.0_armel.deb Size: 4305488 MD5sum: 5e55a403bd2e59e1ad760774970f818b SHA1: 93345cc48529976a61e870e4155c56b90387b848 SHA256: 6e5d8fbd43c4800c00f3b5bdc5b7004c64a8410d29b3f42003dd7ca94fc4283f SHA512: 4c12991a9f44632009b60eedb7fd2c0d02c3c83b9b33ba1b8eeee1d71821e11d09aa02caaf1ef503bbf4204bd238c8c81d36832894afa0b5c5f20d230f148ef7 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-dds Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14822 Depends: Filename: ./1.4.0/zenoh-bridge-dds_1.4.0_armhf.deb Size: 4319976 MD5sum: 21240abf0b442d3acb3ca9b7991590d9 SHA1: 596912ebc925dcc2c33bbfdcf7aab7fa90dc819e SHA256: 7067b74bfad3e088c77126a5d4226d1edb69fb59da734acf4047d09bd22e9a31 SHA512: fbc89a494faa232d605e0abab8f1f4e4851019107f1af665d166941626ee2aff55fa406dbd132854a7032f5ab92c41f78546a12798ebe2131b3d8b744c7c8ef9 Homepage: http://zenoh.io Description: Zenoh bridge for ROS2 and DDS in general Package: zenoh-bridge-mqtt Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16139 Depends: libc6 (>= 2.34) Filename: ./1.4.0/zenoh-bridge-mqtt_1.4.0_amd64.deb Size: 4383428 MD5sum: 13b60bfe388c84d3a331cee3f4980acb SHA1: 033a93f84017733d7253d55bade7ad6ebf913485 SHA256: 7a1530c73744a2b9fa21c298398d6b2ed125b8ca237111c2b6df0ef44a773fe4 SHA512: 98ab037123be0f41f1342101d23e3237718a0eedb78a5a7fbf6c1c26c211cfc92fcb83c3ab8abcf972923b3aba26c845226e4c1cc264eb62d1a71ffce4a89b20 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14866 Depends: Filename: ./1.4.0/zenoh-bridge-mqtt_1.4.0_arm64.deb Size: 3902140 MD5sum: d2aa8e13684de3693769109c5e0a1e4c SHA1: de1c37b422a230534db5f7626fb336c4a211cd01 SHA256: d4d1c3350b3bcb2d0a950406adcf569305a4dbeb7dd64b6418d4fe4a9c7b8e41 SHA512: cede560164df24c0eba29cf5df8a9b3b5828ca9e6b411935225206f98d926d673913eae2da9283ad14fdcbc2aed149fca9289f933df98d9ff23a484e743d0530 Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15454 Depends: Filename: ./1.4.0/zenoh-bridge-mqtt_1.4.0_armel.deb Size: 4025628 MD5sum: 13e7a014ac871d3432659f78a8f9ca62 SHA1: d6f427070137323b41716e40c61e77e21c818caf SHA256: e5dc867e0096e149545fb3712390e05066af3bbeaa54128571fc512b36d4bd0c SHA512: a88d065906be2ed8840f4eea9134726f6a1124b3f73082ad62eaf4b299650831c0dc1c5adade3b9702a926e16cffdfc387b08b263ac94438454a172bb82f475d Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-mqtt Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15127 Depends: Filename: ./1.4.0/zenoh-bridge-mqtt_1.4.0_armhf.deb Size: 4017032 MD5sum: 499753224cb6699ef99fa11f1ad80189 SHA1: 9f071fd56362995e586bf0562e1d4bc1248e307a SHA256: 2a44004fa7bd6f8af1acccaacb374cd73f7990a5f0bcb445df2f552b2f9f9a5c SHA512: a7a2482efeba0df3da973a30a4814c4d7004f586dcdedb07bfb5f61472420d7a23f259a4def9dfa76af1d7ee592241bb8ad486d480fb1df1389648ccbd115ddb Homepage: http://zenoh.io Description: Zenoh bridge for MQTT Package: zenoh-bridge-ros2dds Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 16819 Depends: libc6 (>= 2.34) Filename: ./1.4.0/zenoh-bridge-ros2dds_1.4.0_amd64.deb Size: 4812192 MD5sum: b98bd7fbec033545478b9686db2ab3a3 SHA1: a0b1a119d3d675aba4cbb6f9d51d026c009225d9 SHA256: 8c532ac511aa1b89379de0fd28d2790fb146142a5712ffe209af103b39d53a1e SHA512: 6c34305139072976e8504f2ccb532718d1291f5e095883c39bdcb6ffd46a9b9825bea70b34c6d26ce0c24772a5607883b181fb76588b497ff3d8803d04bf7ee6 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15492 Depends: Filename: ./1.4.0/zenoh-bridge-ros2dds_1.4.0_arm64.deb Size: 4302788 MD5sum: 75d2f2f866b67ce4303685ac2050c7de SHA1: 5c83a80055f1247ed0b12e1376bb8d47a0f15a29 SHA256: 531edafaeabeb64b2c725efceb3888578099656d4dc8345d2ed380edd66a5e30 SHA512: 4efcfedf794d83773f9838d76af38e25463d7d1da8c84b7f80ae505eb839a2e584493a075fd3e84fcb12d6dbfbfef9f85cc9af345e2fbdd1bb5cbae902913e7a Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15887 Depends: Filename: ./1.4.0/zenoh-bridge-ros2dds_1.4.0_armel.deb Size: 4421592 MD5sum: e1d5f0b8a4a7f31cf90a106cc7a1c0ae SHA1: 2c63446c8022ec63a0811deb08afa70a513be819 SHA256: 6f858d24f7dc27b8bb38a80529c3907774d3e34d3151a3aec0b7be35fd14509c SHA512: a2fac0a57b7c75e1ce9fe69e3066abb23802292d8a7cfbefc309b2f2cc744f75e4b4c3df9309749d22c1daa03e753eafd05d5529cc4ab16ff7ceeba0e040af00 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-bridge-ros2dds Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 15345 Depends: Filename: ./1.4.0/zenoh-bridge-ros2dds_1.4.0_armhf.deb Size: 4428088 MD5sum: 2a89a95033b4e0c3569844e049cb7f0d SHA1: 33cf0daaf5ec651dfe070de4da83c33d03931695 SHA256: b161e1ec484b22e57f844162b69fb0a1969ebb4677db3d4ec69321decf4d0d6f SHA512: 3935f213c723b3e563de30cfce2dcbd44b82f45f4e41bedf9715c214ee9a4f22af86f3a16ff5a090c30b2cb630c941d9e2e013148c81fbaa02ba9c4ae41d9145 Homepage: http://zenoh.io Description: Zenoh bridge for ROS 2 and DDS in general Package: zenoh-plugin-dds Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6358 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-dds_1.4.0_amd64.deb Size: 1722116 MD5sum: f976428426a90c1ea1800cf137d098d7 SHA1: f249f4117ba555c07b8363140823910b981db2fa SHA256: 1c605350b328cd4ba337decb5c3e516f138d5e1b5d69ea8d4ee2dc6fa122b711 SHA512: 60f816d8d96b1ea03d36cdede71ee7cc3f7482dc2529d519df87651281d13ce38ddd4260a1120fd9870b9fada055f7a49bae1badbbd54c91fa75fd57aec35008 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 described 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/](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](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: : 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6283 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-dds_1.4.0_arm64.deb Size: 1571868 MD5sum: 1efbaab9327d9b6fbbc0b7e9a84c8f58 SHA1: 54c889ced312e2043dd6701f77b70952211aa901 SHA256: d6bb1c911f8ed33a825e60810c16216802bc519deb3d40a3fa28c5a156b0e1bc SHA512: af97ae0fe615ee03ad9161fd0dd89bc7808390a5642986845fee13dd761ed1444d0a1bfa369b7cd860a5d7e8a054f10ad6e4e6b491798d6878ac83b18ab61d16 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 described 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/](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](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: : 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5873 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-dds_1.4.0_armel.deb Size: 1579184 MD5sum: d3e94a2f0e769d40d1c1ca9a10bbfd9b SHA1: fb80c653fc216acc68b220e4258bc16ce5e116bd SHA256: 5f94bc622e44f04e6d98aa884caa8c6c19b08e2d9a6c4154827e4f264e71c073 SHA512: e456de0e19bf01cbe44f6a451343923c6863a390979afa3357a95561eedaf8b69a3cb9a284bd3d38d0441fc9d6c1f38af544957810f533e765203bc355a73974 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 described 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/](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](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: : 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-dds Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 5517 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-dds_1.4.0_armhf.deb Size: 1595660 MD5sum: f534e33b0b1977a4b59d1a5a8a495124 SHA1: dff1794680fc76513a1d53351dd7e02ecd1a4df1 SHA256: 668b3d9b36f973fd3af585b7854938c23d542002b3fa641dbca089e72bbc2f30 SHA512: 30ddb36ebef4a8ce5a272a297f5736dbccd398605f2e9132b6b7001ad3666a0efd3e8f43b09c303f83c87ae312de649c880dedeb3f6e6a3ea7b2f208e4b83d11 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 described 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/](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](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: : 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 PSMX plugin based on the [Iceoryx library](https://iceoryx.io/). Iceoryx introduces additional system requirements which are documented [here](https://iceoryx.io/v2.0.5/getting-started/installation/#dependencies). . **Note:** To ensure successful communication the entire system should be built to use the same version of the Iceoryx Library. **The Zenoh DDS Plugin currently uses Iceoryx v2.0.5.** . 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. . #### Shared Memory Limitations . The following limitations apply to Cyclone DDS shared memory support in the plugin: . - Shared memory is not supported on Windows systems. - When DDS shared memory is enabled the Iceoryx PSMX plugin will be instantiated with the default configuration. If additional configuration is required the Iceoryx plugin should be configured via the `CYCLONEDDS_URI` instead. - In forward discovery mode DDS samples will not be forwarded via Zenoh unless the DDS data type is memcpy safe. A data type is memcpy safe if it does not contain indirections. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-ros2dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the DDS plugin with prefixed DDS library symbols. e.g. . - plugin library: . ```bash cargo build --release -p zenoh-plugin-dds --features prefix_symbols ``` . - standalone executable binary: . ```bash cargo build --release -p zenoh-bridge-dds --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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 embedded 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. - **`--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 the Iceoryx shared memory PSMX plugin with default config. 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](#architecture-details) - **`-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 information is 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-of-dds-topics-to-zenoh-keys)). - `@//dds/route/to_dds/` : a route established from a zenoh key named `` (see [mapping rules](#mapping-of-dds-topics-to-zenoh-keys)).. . 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: . ```raw 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` | Package: zenoh-plugin-mqtt Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7687 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-mqtt_1.4.0_amd64.deb Size: 1923564 MD5sum: 2ba5222786c5ee1311c077d9122e95f7 SHA1: fc0f0cf7373e0ce9c47cacce0b7e853d2f0f72b8 SHA256: e5b44f9ba47bd1b7ec129d13a865720874e04fd715dc29338d18b8695add4217 SHA512: af6c04525affc7917580bc604e1e600281a67c2ae5c357a06e22e8c812b96a8e6372292422e0db9f057eaa7df82e3a50b5ab87772b7e4432f41a9cf3f23a8086 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: . ```raw 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/](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](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: : 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. Package: zenoh-plugin-mqtt Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7464 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-mqtt_1.4.0_arm64.deb Size: 1751760 MD5sum: f763b967420011016e42f386e0f6e34c SHA1: e32572ef6e1ca2fff795868ae2e4918b5fd797b3 SHA256: c559858e34309790c23fe74a2dbccba36b1dafa54427085928ef0a8df3c4f139 SHA512: 4eb3b535377f9539218ff904da587a819be7fad320ee4bd6d877d53ebc4610b75d8a02fb5e11e6d7a8196e5da2053daecfb75187d8eb5684c8c9e71ca3fefc02 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: . ```raw 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/](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](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: : 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. Package: zenoh-plugin-mqtt Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7077 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-mqtt_1.4.0_armel.deb Size: 1639376 MD5sum: 6157639db4b114c88231140c27a70243 SHA1: 95d2b520c58fe33e5257ed639f65410c8691538e SHA256: 80d0a70c73848e4405b589a194bb1fd70d767b3f0e726ac071c505d065edf759 SHA512: e1346b5eab1280d11df9f629062881cea15253c9447bd718d12e51c9f07408a92907d65d68438786062ac900e541e056d12f055342f4b83717f2e7837a197ad9 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: . ```raw 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/](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](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: : 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. Package: zenoh-plugin-mqtt Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6917 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-mqtt_1.4.0_armhf.deb Size: 1647644 MD5sum: ffe7536bfde87fa47dbbd8f90b728081 SHA1: 15a5ca39760d16a0c6e87304870e103c8f2a4559 SHA256: 336a46d7d3b1e6407884b0b60a53166966bb1d56d5447d448d65b31cc2812e75 SHA512: 7b2348ce9fa6b36922bcb32d64fff399c17fad0ccf91df45d0bfab958a1f05fa8d2495642e6d4f12298b21560b2f4737a231cb3ba37ec1cf94d4ea51d6710d94 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: . ```raw 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/](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](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: : 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. Package: zenoh-plugin-remote-api Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9590 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-remote-api_1.4.0_amd64.deb Size: 2428380 MD5sum: 5ea687ad26236741f3abff61e5ce5522 SHA1: 55a99931fcb9c05762c1ee00c50db0597b9f35b6 SHA256: 3f6c2cebfde57e8ffd3b992b59ad845ad7a08b9e72eb3230a9949009c7d24e75 SHA512: ab1e026ade933439a26b01b346789eabb3dd1418d32abe105326a647e2fb9ee0d49c8680ea11c5ab49cd93f818e53b8426ffe5b5a5b548d81def990b83521102 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 9634 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-remote-api_1.4.0_arm64.deb Size: 2254572 MD5sum: 84699b2a3a2747390044e18ff9867e51 SHA1: 5006382957c9048da019ce621cfaab551c9dbd7e SHA256: 96cdb5f05ed09d4c8fb8e05a12f35eda286d54b0f9c946fd74a08577bf2e7103 SHA512: b4e85a2ffe682b6a5e60c88b862fb21bd0f9b29367c3d48d115173eb19cb76e1cc8d4bce51d14c773a809fd02441b78bd53ed058e08a318a6340c1e259cf6e2d Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8654 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-remote-api_1.4.0_armel.deb Size: 2033420 MD5sum: 6a65445a34b7f020ede8d55d5a04a05c SHA1: a2bb6069ab5c04465dca292efe378321e04a7665 SHA256: 4eb00c0d38e36cd961c213abf65e2319bf9ba89c7f16560dedd1264e609c7948 SHA512: cc093f8314214564930531fcc0402a6a54d6da26af5174e63f667ade13ad04f194f880a76ce31171594505ba31dd613b911e62e61462ae5c5aa101d08f066bc3 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-remote-api Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 8482 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-remote-api_1.4.0_armhf.deb Size: 2045296 MD5sum: e5b8ee2169d1be9e5e5e8d0e0a2b78eb SHA1: 63c9dc5b3a833b6ff7e2edd21a9a6eb75c5a1b47 SHA256: 85c0a681a9febbc2da5fdc8f71dc6c2b5e3b87d88e0fcdc7bdda1dfe65585e39 SHA512: 998e66f2c5c300597256730180a9ff82e83b364b0d5a2b6fdfa4ec66442c285d866382e177edc7e55201cc4eb846f26172ef09c8b7188ebbd7c651ad6a0a48ce Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. . Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. . ------------------------------- . # Remote API Plugin . In Zenoh, the remote API plugin is an library loaded into a Zenohd instance at start up, which allows the creation of a Session, declaration of zenoh resources (Subscribers, Publishers, Queryables) remotely via websockets, for runtime environments where it is currently unsupported to run a zenoh binary. The Remote API was designed to support the Typescript Zenoh bindings, running in a browser. . ------------------------------- . ## **Examples of usage** . Prerequisites: . - You have a zenoh router (`zenohd`) installed, and the `libzenoh_plugin_remote_api.so` library file is available in `~/.zenoh/lib` or `~/target/debug`. . ### **Setup via a JSON5 configuration file** . - Create a `zenoh.json5` configuration file containing for example: . ```json5 { mode: "router", plugins_loading: { enabled: true, search_dirs: ["./target/debug", "~/.zenoh/lib"], }, plugins: { remote_api: { "websocket_port": "10000", }, }, } . ``` . - Run the zenoh router with: `zenohd -c EXAMPLE_CONFIG.json5` . ------------------------------- . ## How to build it . > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent 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 zenohd . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` is version `v1.0.0-beta.2` has been built with the rustc version `1.75.0`. Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` . And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: . ```toml zenoh = { version = "v1.0.0-beta.2", features = [ "unstable" ] } ``` . Then build the plugin: . ```bash cargo build --release --all-targets -p zenoh-plugin-remote-api ``` . ### Example with a version built from sources . ```bash $ zenohd --version zenohd v1.0.0-beta.2 built with rustc 1.75.0 (82e1608df 2023-12-21) ``` . Here, `zenohd` version is `v1.0.0-beta.2` where: . - `v1.0.0-beta.2` means it's a development version for the future `v1.0.0` release - `82e1608df` indicates the commit hash - And it has been built with the `rustc` version `1.75.0`. . Install and use this same toolchain with the following command: . ```bash rustup default 1.75.0 ``` Package: zenoh-plugin-rest Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4607 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-rest_1.4.0_amd64.deb Size: 1240056 MD5sum: 7332992d6bd22bd9d41e4de52d98ffb8 SHA1: 86728a278659498e654b32d981f8f3c771f58e83 SHA256: ecfec093c6069189a873aae10381d13372c9b1f9a69517ce6cd3a3d3a49871a3 SHA512: a12eaf2851b4373f797efb2a3fc512dc485dc77902b646f43a742bd1a4f9e2e3d780e51e5c8c1e23e5acf072c854046f78cec547b1c8be9cfbbfd6052ccfd0c5 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4652 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-rest_1.4.0_arm64.deb Size: 1145896 MD5sum: b8e3d4d2e9dc610fa88b354ade736870 SHA1: dc3f95ca6ab82c0b54aaff954a520e27ba60fed5 SHA256: 225128b2f59321794ef1c27d6526a4623dcc5670b3220df16646b40c704336ac SHA512: 299ef278bd2b8bbb86445f7ea7514aef84ec2698d9299d1b02f3cd240a763fdccb99d4e88ecd2a4fec0c472024cbaa8af82858725719895bc0fd1a32fef03c81 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4385 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-rest_1.4.0_armel.deb Size: 1186484 MD5sum: 8fc99d3dfae2b62c7bfcad047cdd9452 SHA1: 85690967d1d41127dfcc7ce7696ff03cd17a35c0 SHA256: 48551626612a4319a8170e5c46cb69df569711d185d03801c545b7563654322a SHA512: 4f43e48396086c792c71ef368ea04f78e24f7ad30ec8dd1d8c4b8593b2bb9098d1a83446aa30d1d4a39f9fa53c3d015dc6e5ff621daf39ca9eb6d355a1fa3cf4 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-rest Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4312 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-rest_1.4.0_armhf.deb Size: 1182200 MD5sum: 336c37b3c7991c7b089dbba48b775dbf SHA1: 26ef29c43fe4d4e47e39c85f690b0a537f8227fd SHA256: 25a6cf008292cee4dfb1925a5d12597ac4c159925729e4700ca7729662ae1e85 SHA512: a2efe279c42bdc007e69afe03c96f8d7a7085b44eb9bde3954afcf16860614e5748b9e4ec2e38f0c84ed3dac6c12a32db3ae6d119abe1569c0e3085129f27e26 Homepage: http://zenoh.io Description: The zenoh REST plugin # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-ros2dds Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6885 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-ros2dds_1.4.0_amd64.deb Size: 1811872 MD5sum: d0fd922e43c74fb68046e8e9eabfe6be SHA1: 92502dcfadeec8ae6fd0489c32df3bcf72a9ea31 SHA256: b5a65af580d38d1cc61ebb5e5a86acb88dbccc1abf4e12ec9b932939f2166160 SHA512: 4973d3bf7d17fafca571721173afc21d157bc13fa07e43b7f69d8ed7d34b25f8ea38660d75cdc17634bedcd0b8e5f6b720d96e38476d212be08850d75a17effd 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 described 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/](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](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: : 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6775 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-ros2dds_1.4.0_arm64.deb Size: 1652172 MD5sum: 9952e9779ab2daebe1afdfccde260a4e SHA1: 3585004c671bd3a1c01a21b85dce2f605fd9d142 SHA256: 60d7efba74e5e0d31e51ca0938b3c5ce2f1e2f32b8a31d320667c86ad2716b3f SHA512: d7ebcbe68a205c103b42a62c1a551c34e18fc365e0aa32084c23e3c551ad76cdc026218fd8a30523834e30fbbce0985a85a520177659d1ce61f5cd6e0f22abb6 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 described 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/](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](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: : 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6343 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-ros2dds_1.4.0_armel.deb Size: 1669916 MD5sum: 839a9f8d595a561d49bfebe04533f7a7 SHA1: acc0c6ffd8d28841423656c588402d5ef426a987 SHA256: b556e03080ff755d26a724f0ae747a4ad290b84c21addc7c99f8f892ac0c6b55 SHA512: e3461c1a5a1319e7c41e0999355808a6255dde0b8c995c8cd75c39b5fba05db89680ee4d046072a98224aa9d951ea6023a2fad37c4b19f9132d1f86e2b331cdf 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 described 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/](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](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: : 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-ros2dds Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6007 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-ros2dds_1.4.0_armhf.deb Size: 1692104 MD5sum: ec092c17d24375d543ca06f49f2ab409 SHA1: 4c4f121513f618102b71778407c655a549286082 SHA256: d6f0713e1d387dd6edaea5162a4b43e0cda4bd012913a76dd3d04537769da2f0 SHA512: 634ef17404179b1bebfd644a80cfb020aaf785f9fd737111f10ae142238b0095572fb69d0cadd4b82662cbd3b20a7cdf30ec9d2bb9cf999bcbefdf8ccd845bd8 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 described 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/](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](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: : 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. . ### DDS Library Symbol Prefixing . DDS support is provided by the [cyclors crate](https://crates.io/crates/cyclors). As this crate contains C code, symbol clashes may occur when loading the plugin statically with other plugins which use a different version of the ```cyclors``` crate (e.g. the ```zenoh-plugin-dds``` plugin). . To allow multiple versions of the ```cyclors``` crate to be loaded at the same time the symbols within the crate can be prefixed with the crate version. The optional ```prefix_symbols``` feature can be used to build the ROS2 plugin with prefixed DDS library symbols. e.g. . ```bash cargo build --features prefix_symbols ``` . **Note:** The ```prefix_symbols``` feature cannot be used at the same time as the ```dds_shm``` feature. . ## 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 architecture 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: . - use ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST after Iron and ROS_LOCALHOST_ONLY=1 before Iron. 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 possible 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 bridge, 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 Zenoh 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, such URLs can be queried: . - `http://\:8000/@/local/ros2/node/**` : to get all ROS nodes with their interfaces discovered by the bridge - `http://\:8000/@/local/ros2/dds/**` : to get all the DDS Readers/Writers discovered by the bridge - `http://\:8000/@/local/ros2/route/**` : to get all routes between ROS interfaces and Zenoh established by the bridge - `http://\:8000/@/*/ros2/node/**` : to get all ROS nodes discovered by all bridges - `http://\:8000/@/*/ros2/route/**/cmd_vel` : to get all routes between established by all bridges on `cmd_vel` topic Package: zenoh-plugin-storage-manager Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4341 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-storage-manager_1.4.0_amd64.deb Size: 1134400 MD5sum: 91cfafc2d0b2ef01730e8f4cb2f59f70 SHA1: 476152176255f1908eeb961017147ecc9a2e9eb5 SHA256: 1f7630728ffcd07050bba39bc66c4eef1ec3a0b1840522d3af387f93e1a587ba SHA512: 04af164801b0c2408f906d259bf7fb25c579dea95ed6fd52bcb91167510fed297130a8b98660ed4295ead135366c247c79f5c90b82f6fc459e8daf924c04a8f8 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4365 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-storage-manager_1.4.0_arm64.deb Size: 1049664 MD5sum: 8b0762042a017af40b2c5fbda1a4d8a0 SHA1: 4d1225f076575294a395ef314107a735a2a856e7 SHA256: 8d93c6dff015f94593cdf1d20a1da102a65cc20060818222158960218a63dc7c SHA512: caa71fc4a4fdf56394f014640876c9af13d4f0ffb49a46c2e38cf68b35692ee799a2d92ec6b83300eb2f767bb34635887c58d369dc22aef019938daa72ce01fe Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4130 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-storage-manager_1.4.0_armel.deb Size: 1100172 MD5sum: 488a7757d74b364f55c73d93f8c9a314 SHA1: 6659ac7dee1a424d09a3759750d7144ba9d0dc76 SHA256: d73487150f36c0c4df50aee288f6c3cfa1b897be06fbf0659d97d3e66744a3c2 SHA512: 1ce66ffccf63e902572be840f3fa24fb8b10fa5d38fdfb72e6bec4b5b80bb57154fdc74011bb3ea8ae64d3ea19ea832cf41fe0c7b8c1103613bf6d0c0a77977c Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-storage-manager Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 4041 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-storage-manager_1.4.0_armhf.deb Size: 1094368 MD5sum: 1bf5e3b26a76bea3e6233f424402fcaf SHA1: 89ef673ad87ea3a6d37998a53be6628c7a95d836 SHA256: 4906dbc4afc0aec96e714c93743b70d1dd126264ccc654784a27201b5fdfeabc SHA512: f4c7adb070d1c5e844bb8a6e1fce6cb78003515cb3fc3052ea41cda9473d75a48cf998a0bfe6685631fa8d08da3f10153af879af08cd075d5e119a93567aa8e8 Homepage: http://zenoh.io Description: The zenoh storages plugin. # ⚠️ WARNING ⚠️ . This crate is intended for Zenoh's internal use. It is not guaranteed that the API will remain unchanged in any version, including patch updates. It is highly recommended to depend solely on the zenoh and zenoh-ext crates and to utilize their public APIs. . - [Click here for Zenoh's main repository](https://github.com/eclipse-zenoh/zenoh) - [Click here for Zenoh's documentation](https://zenoh.io) Package: zenoh-plugin-webserver Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6951 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-webserver_1.4.0_amd64.deb Size: 1651128 MD5sum: 060504fb1ada0f5adcdaee3aa35e9ffe SHA1: 3e4878dcab54391ee4c454d105aa63aa196eaccc SHA256: b2f699ef260c6e4c41dd236e68daf98201ea0d32b66fd9ed0206d7ccf7100a5d SHA512: b4806074a6cbb903fe4a7e599a1dbb6d28a3d6770e26f26329b6b67513cff8811991047cedeef9ed9548dc6a04158a4cb3faed78a5af30e1e5bcf145b5943cc1 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/](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](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: . ```raw [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: . ```raw [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: : 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 ``` Package: zenoh-plugin-webserver Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 7198 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-webserver_1.4.0_arm64.deb Size: 1552136 MD5sum: a9dd1af2be0a5e633a359894e9fe6971 SHA1: de059b5034a6148fd8cb0152128981947eb70668 SHA256: fbfe82b51489da3a50a0f5f45c2db7f540cdf2054fb6ee60236c1797068157e2 SHA512: 103db06796f7c0e3ca448cf4e3bf6c63d89e329c42914ed033a055ec984640914749c3e7375458bdbf55b21017d17f59b736b355e8d240f93995e8eb4600cb7c 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/](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](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: . ```raw [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: . ```raw [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: : 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 ``` Package: zenoh-plugin-webserver Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6492 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-webserver_1.4.0_armel.deb Size: 1527604 MD5sum: febef65d76e1f546e6e117a546ad495d SHA1: a846a886d80fc0ac94dfc8f50eaf51c09cebdb2e SHA256: 5a1dbc7c707184dedcf8d76f08a966dcbd48260e959d767ae14808671f5062c7 SHA512: 199509c4e46f6edd288e73686ba54ee59b4653a41cee83b6e51efefb595b3ea430c80ae800e24c6b130b933fc35066ee87a72a4235992251ca8a6d4ef51a9ff4 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/](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](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: . ```raw [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: . ```raw [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: : 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 ``` Package: zenoh-plugin-webserver Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 6394 Depends: zenohd (=1.4.0) Filename: ./1.4.0/zenoh-plugin-webserver_1.4.0_armhf.deb Size: 1523840 MD5sum: 31a713d5cdfed64aed9b1603f758b2e8 SHA1: f8b89d9f6eec55d123a288837af4178d3bc76c35 SHA256: 5953af68af07c6b834938c0d142a4eefe30115c40a74ed216edbd48dfd89a74d SHA512: f94714a976c29fca4ea0212c5ab98c7a98625060f9e0d4a168f2495c1c31dc4bfb536d9f55d457b8aec9a3a33379c61e7df451eb051ab710b1ba7e4a6fb9c394 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/](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](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: . ```raw [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: . ```raw [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: : 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 ``` Package: zenoh Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.4.0), zenoh-plugin-storage-manager (=1.4.0), zenohd (=1.4.0) Filename: ./1.4.0/zenoh_1.4.0_amd64.deb Size: 16964 MD5sum: ba6041ffa760d6e2084f7855a820d457 SHA1: 1b4960b6adae8c6e564dbcfc70c3eac1a9338fbf SHA256: c6ea8f19a460c777ebaff64d42f2ff33aee3651c8e683a983bbebc74d1567841 SHA512: aedaf6e974c6dc5b60d235cabdd00102770f736a867d739d83f6175e0452d3a24ed3b3dcd35c2fdfd266f910bb566c9276127f8f962e40c6ab930aca27d8cc94 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.4.0), zenoh-plugin-storage-manager (=1.4.0), zenohd (=1.4.0) Filename: ./1.4.0/zenoh_1.4.0_arm64.deb Size: 16964 MD5sum: 1425a08017869eb310410850de6f0c36 SHA1: 8a491cb0797bd81e516cc5852f14690c3aeb3145 SHA256: 44b0bd06af16a01ae31fa8f99db814cd259e27a6d9f66acb15a87079295f000c SHA512: 12886f21e978f2b04c6bf53c1ec82eb580dd71703bcb10ac25569287ec3e91d4e98ae922203da1910024ec8537c00602ce1d8d6a13a1036810a865cfbe71c2a7 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.4.0), zenoh-plugin-storage-manager (=1.4.0), zenohd (=1.4.0) Filename: ./1.4.0/zenoh_1.4.0_armel.deb Size: 16960 MD5sum: 9b0b5c8b31eadf6e8e30a6fe77b06168 SHA1: dd4443ae06014a171e4214f2bf5635a6ca1ae1bf SHA256: c6e41499a159abfbc050c5157a24235aa7eabf5870561badf6a933a6d918a3c0 SHA512: 7309942355d6e005c69d2e19a879a1ae7f1e02bcc65804d69bf42bdbe6d994f8c06d70db70970a3d8608e04ab28a45f1073bf840df634440ed2310e568792103 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenoh Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 40 Depends: zenoh-plugin-rest (=1.4.0), zenoh-plugin-storage-manager (=1.4.0), zenohd (=1.4.0) Filename: ./1.4.0/zenoh_1.4.0_armhf.deb Size: 16960 MD5sum: 2308abd0b1927b0e0ef8419d50a075cf SHA1: 83cd382d00a45235c5f7233ec9763912b2df47e0 SHA256: 1f1557ca198ce25a2fd665a6d21b9adcd5be3f13f43ae00bddb765e292aab4f1 SHA512: bcfe484cc99abcea7cf42c80ce87cd29b4cef52826b1af05f5b98f15d424ab1acd20d54c0e59c42c50c9e57089a452f3d8fd19094203475b9641e6c5f532e567 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: amd64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 14541 Depends: libc6 (>= 2.34) Filename: ./1.4.0/zenohd_1.4.0_amd64.deb Size: 3948212 MD5sum: 5d7a25b32b4ed8190fb7a7470af68208 SHA1: 7bfb62d5e2ff7190f84e42f037884906ffe1b49e SHA256: 742277b38468bf70170f46a70702a7766d16d6d2f2288cd153c6ab79c7a63309 SHA512: 62cd14b731c0ccb08ecdde38d26a52d6685b1e331451f250a5b2c3987eb10d5ca38b4a0e164d59a11000e60dd1e7dbcdcb2c8e45d1c175d5e80def6081b98dd0 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: arm64 Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13061 Depends: Filename: ./1.4.0/zenohd_1.4.0_arm64.deb Size: 3517868 MD5sum: e75d135858ed625c325af0dc7fb3db5f SHA1: 3979f6a04f838634c24aa9707d14c7f2f0c1dfb0 SHA256: ca09f9869ced269c426db80ef1734eb53b4a5214fcc06fea96a4da8226deefee SHA512: 6f8c3b91daf2d2dda452ce376e364ba4972ee1f169bf807bb1f035409128e708ca15f071ccfdba746aa450668337ef4058728796e786fed889557b826762fb39 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armel Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13776 Depends: Filename: ./1.4.0/zenohd_1.4.0_armel.deb Size: 3693212 MD5sum: cc90d0582de6bbfa6895b496efc15f60 SHA1: 4a992c11436292c038c9c1fcaaaad3d46155de1d SHA256: 4aaeca8cd67263fa61b6121c11db990b2f3562f7383bb3b752677d8551dd69ad SHA512: e3735d0baab81bf402c1ab45ddcaeacdf198b193b98287cbe67dc5a53bbb5131eb2b97f2df4f90c233f9069550de293cc3aaf51540c232b206c84f2d45186fa2 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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). Package: zenohd Architecture: armhf Version: 1.4.0 Priority: optional Section: net Maintainer: zenoh-dev@eclipse.org Installed-Size: 13502 Depends: Filename: ./1.4.0/zenohd_1.4.0_armhf.deb Size: 3713904 MD5sum: 55219f62eddefa35150eee77b20e38a2 SHA1: df2aecd0493b7401700057a8d532c75bfcd2f9aa SHA256: 725331d046d3816af914f607a1ddf2c6f1cfa646ae086f8766a703ec4edba644 SHA512: 4bf8876d9a23e5f4e609248813c09151e9fcb7bafa77f9753bc06520267ba856dadcc6026272227d0935e009159f0fccd102eaad30cec0eaaf787541a2cdc135 Homepage: http://zenoh.io Description: Zenoh: The Zero Overhead Pub/Sub/Query Protocol. . [![CI](https://github.com/eclipse-zenoh/zenoh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eclipse-zenoh/zenoh/actions?query=workflow%3ACI+branch%3Amain++) [![Documentation Status](https://readthedocs.org/projects/zenoh-rust/badge/?version=latest)](https://zenoh-rust.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/github/eclipse-zenoh/zenoh/branch/main/graph/badge.svg?token=F8T4C8WPZD)](https://codecov.io/github/eclipse-zenoh/zenoh) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue)](https://discord.gg/2GJ958VuHs) [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) . # Eclipse Zenoh . The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. . Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of 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/](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](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 . * [Docs.rs for Zenoh](https://docs.rs/zenoh/latest/zenoh/) . ------------------------------- . ## How to build it . Install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Zenoh can be successfully compiled with Rust stable (>= 1.75.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: . ```sh ./target/release/zenohd --cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}' ``` . * in another shell run: . ```sh ./target/release/examples/z_put` ``` . * then run . ```sh ./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: . ```sh ./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: . ```sh curl -X PUT -d '"Hello World!"' http://localhost:8000/demo/example/test ``` . * get it back via the REST API: . ```sh 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: . ```sh ./target/release/zenohd --rest-http-port=8000 --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 (you may use `jq` for pretty json formatting): . ```sh curl -s http://localhost:8000/@/local/router | jq ``` . * get the volumes of the router (only memory by default): . ```sh curl -s 'http://localhost:8000/@/local/router/**/volumes/*' | jq ``` . * get the storages of the local router (the memory storage configured at startup on '/demo/example/**' should be present): . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . * add another memory storage on `/demo/mystore/**`: . ```sh curl -X PUT -H 'content-type:application/json' -d '{"key_expr":"demo/mystore/**","volume":"memory"}' http://localhost:8000/@/local/router/config/plugins/storage_manager/storages/mystore ``` . * check it has been created: . ```sh curl -s 'http://localhost:8000/@/local/router/**/storages/*' | jq ``` . ### 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 deactivate the REST plugin . If not specified, the REST plugin will be active on any interface (`[::]`) and port `8000`. . ------------------------------- . ## Plugins . > [!WARNING] > As Rust doesn't have a stable ABI, the plugins should be built with the exact same Rust version as `zenohd`, and using for `zenoh` dependency the same version (or commit number) as `zenohd` with the same set of features. A plugin compiled with different Rust version or with different set of `zenoh` crate features will be rejected when `zenohd` attempts to load it. Otherwise, incompatibilities in memory mapping of structures shared between `zenohd` and the library could lead to a `"SIGSEGV"` 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. . **[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. . Note that to activate the REST plugin on `zenohd` the CLI argument should be passed: `--rest-http-port=8000` (or any other port of your choice). . **[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).