From 21dde18c6f032cea88832ba47d579e959d36241c Mon Sep 17 00:00:00 2001 From: ChenYing Kuo Date: Wed, 18 Dec 2024 14:30:49 +0800 Subject: [PATCH] Add CI for checking markdown format. Signed-off-by: ChenYing Kuo --- .github/workflows/ci.yml | 11 +- .markdownlint.yaml | 7 ++ README.md | 257 ++++++++++++++++++++++----------------- v1/README.md | 247 +++++++++++++++++++++---------------- v2/README.md | 220 +++++++++++++++++++-------------- 5 files changed, 427 insertions(+), 315 deletions(-) create mode 100644 .markdownlint.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c322f5..5b7b02f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,15 @@ jobs: - name: Run tests run: cargo test --verbose + markdown_lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: DavidAnson/markdownlint-cli2-action@v18 + with: + config: '.markdownlint.yaml' + globs: '**/README.md' + # NOTE: In GitHub repository settings, the "Require status checks to pass # before merging" branch protection rule ensures that commits are only merged # from branches where specific status checks have passed. These checks are @@ -59,7 +68,7 @@ jobs: ci: name: CI status checks runs-on: ubuntu-latest - needs: build + needs: [build, markdown_lint] if: always() steps: - name: Check whether all jobs pass diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..144a095 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,7 @@ +{ + "MD013": false, # Line length limitation + "MD024": false, # Allow multiple headings with the same content + "MD033": false, # Enable Inline HTML + "MD041": false, # Allow first line heading + "MD045": false, # Allow Images have no alternate text +} \ No newline at end of file diff --git a/README.md b/README.md index 7cb84bc..96ccabc 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. ------------------------------- + # InfluxDB backend In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the @@ -25,119 +26,127 @@ This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxd to implement the 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: **Install latest release:** see [below](#how-to-install-it) -:point_right: **Build "main" branch:** see [below](#How-to-build-it) +:point_right: **Build "main" branch:** see [below](#how-to-build-it) ------------------------------- -## :warning: Documentation for previous 0.5 versions: + +## :warning: Documentation for previous 0.5 versions + The following documentation related to the version currently in development in "main" branch: 0.6.x. For previous versions see the README and code of the corresponding tagged version: - - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) + +- [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) +- [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-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 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 and influxdb2 for v2 - influxdb: { - // URL to the InfluxDB service. The example below is for plugin v1.x. For plugin 2.x, we need to append /api/v2/ to the url - url: "http://localhost:8086", +- 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 and influxdb2 for v2 + influxdb: { + // URL to the InfluxDB service. The example below is for plugin v1.x. For plugin 2.x, we need to append /api/v2/ to the url + url: "http://localhost:8086", + private: { + + //For detailed explanation, see individual README files for v1 and v2 + //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; if you have no admin creds, you can copy the user creds instead + // org_id: "organization ID", + // 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 and influxdb2 for v2 (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 detailed explanation, see individual README files for v1 and v2 //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; if you have no admin creds, you can copy the user creds instead + //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 + //the org_id value should be the same as for admin // org_id: "organization ID", - // 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 and influxdb2 for v2 (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 - //the org_id value should be the same as for admin - // org_id: "organization ID", - //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" - } + //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 } - } + } + }, + // Optionally, add the REST plugin + rest: { http_port: 8000 } } - ``` - - Run the zenoh router with: - `zenohd -c zenoh.json5` + } + ``` + +- Run the zenoh router with: + `zenohd -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` +- 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 @@ -163,43 +172,50 @@ Alternatively, you can test running both the zenoh router and the InfluxDB servi --> ------------------------------- + ## Volume configuration + InfluxDB-backed volumes need some configuration to work: - **`"url"`** (**required**) : a URL to the InfluxDB service. Example for plugin v1: `http://localhost:8086`. For plugin v2, we need to append `/add/v2` to the url. -#### admin levelcredentials: - +### 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 + - **`"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 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) +- **`"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)) Both `org_id` and `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)* + _(the value doesn't matter, only the property existence is checked)_ - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) + - _unset_ or `"do_nothing"`: the database remains untouched (this is the 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. -### Volume-specific user credentials: +### Volume-specific user credentials + #### for v1.x - **`"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. @@ -212,11 +228,12 @@ Storages relying on a `influxdb` backed volume may have additional configuration - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. - ------------------------------- + ## **Behaviour of the backend** ### Mapping to InfluxDB concepts + Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) @@ -224,19 +241,22 @@ named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - - `"timestamp"` field: the original zenoh timestamp - - `"encoding"` field: the value's encoding flag - - `"base64"` field: a boolean indicating if the value is encoded in base64 - - `"value"`field: the value as a string, possibly encoded in base64 for binary values. + +- `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) +- `"timestamp"` field: the original zenoh timestamp +- `"encoding"` field: the value's encoding flag +- `"base64"` field: a boolean indicating if the value is encoded in base64 +- `"value"`field: the value as a string, possibly encoded in base64 for binary values. ### Behaviour on deletion + On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In influxdb 1.x, after a delay (5 seconds), the measurement corresponding to the deleted key is dropped if it still contains no points. In influxdb 2.x, dropping measurement is not supported. ### Behaviour on GET + On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via @@ -246,21 +266,22 @@ the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadma This is due to lack of support in Influxdb 2.x API for our approach. Examples of selectors: + ```bash - # get the complete time-series - demo/example/**?_time=[..] +# get the complete time-series +demo/example/**?_time=[..] - # get points within a fixed date interval - demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] +# get points within a fixed date interval +demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] - # get points within a relative date interval - demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] +# get points within a relative date interval +demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format - ------------------------------- + ## How to install it To install the latest release of this backend library, you can do as follows: @@ -268,9 +289,10 @@ To install the latest release of this backend library, you 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 +- [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) @@ -285,9 +307,11 @@ echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sud sudo apt update sudo apt install zenoh-backend-influxdb-v1 ``` + See the specific plugin (v1/v2) README file for details. ------------------------------- + ## How to build it > :warning: **WARNING** :warning: : Zenoh and its ecosystem are under active development. When you build from git, make sure you also build from git any other Zenoh repository you plan to use (e.g. binding, plugin, backend, etc.). It may happen that some changes in git are not compatible with the most recent packaged Zenoh release (e.g. deb, docker, pip). We put particular effort in mantaining compatibility between the various git repositories in the Zenoh project. @@ -295,7 +319,7 @@ See the specific plugin (v1/v2) README file for details. At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash -$ rustup update +rustup update ``` > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be @@ -304,40 +328,48 @@ Otherwise, incompatibilities in memory mapping of shared types between `zenohd` To know the Rust version you're `zenohd` has been built with, use the `--version` option. -### Example with a downloaded version: +### Example with a downloaded version + ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` + Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: ```bash -$ rustup default 1.72.0 +rustup default 1.72.0 ``` And edit the update `Cargo.toml` file to make all the `zenoh` dependencies to use the same version number: + ```toml zenoh = { version = "0.10.0-rc", features = [ "unstable" ] } ``` Then build the backend, you can specify which version you want to build (here we are showing the example for v2. See the specific plugin (v1/v2) README file for details. ): + ```bash -$ cargo build --release --all-targets -p zenoh-backend-influxdb-v2 +cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` + You can build both the versions as well: + ```bash -$ cargo build --release --all-targets +cargo build --release --all-targets ``` +### Example with a version built from sources -### Example with a version built from sources: ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` + Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: + - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) @@ -346,10 +378,11 @@ And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: ```bash -$ rustup default 1.72.0 +rustup default 1.72.0 ``` And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: + ```bash -$ cargo update -p zenoh --precise 9f7a37ee +cargo update -p zenoh --precise 9f7a37ee ``` diff --git a/v1/README.md b/v1/README.md index bf05a29..5107b7a 100644 --- a/v1/README.md +++ b/v1/README.md @@ -15,6 +15,7 @@ Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. ------------------------------- + # InfluxDB backend In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the @@ -25,116 +26,124 @@ This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxd to implement the 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: **Install latest release:** see [below](#how-to-install-it) -:point_right: **Build "main" branch:** see [below](#How-to-build-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: + +## :warning: Documentation for previous 0.5 versions + The following documentation related to the version currently in development in "main" branch: 0.6.x. For previous versions see the README and code of the corresponding tagged version: - - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) + +- [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) +- [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-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 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" +- 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" - } + } + }, + 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 } - } + } + }, + // Optionally, add the REST plugin + rest: { http_port: 8000 } } - ``` - - Run the zenoh router with: - `zenohd -c zenoh.json5` + } + ``` + +- Run the zenoh router with: + `zenohd -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` +- 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 @@ -160,48 +169,54 @@ Alternatively, you can test running both the zenoh router and the InfluxDB servi --> ------------------------------- + ## Volume configuration + InfluxDB-backed volumes need some configuration to work: - **`"url"`** (**required**) : a URL to the InfluxDB service. Example: `http://localhost:8086` -#### admin levelcredentials: - +### 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) +- **`"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)* + _(the value doesn't matter, only the property existence is checked)_ - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) + - _unset_ or `"do_nothing"`: the database remains untouched (this is the 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) @@ -209,18 +224,21 @@ named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - - `"timestamp"` field: the original zenoh timestamp - - `"encoding"` field: the value's encoding flag - - `"base64"` field: a boolean indicating if the value is encoded in base64 - - `"value"`field: the value as a string, possibly encoded in base64 for binary values. + +- `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) +- `"timestamp"` field: the original zenoh timestamp +- `"encoding"` field: the value's encoding flag +- `"base64"` field: a boolean indicating if the value is encoded in base64 +- `"value"`field: the value as a string, possibly encoded in base64 for binary values. ### Behaviour on deletion + On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. ### Behaviour on GET + On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via @@ -230,21 +248,22 @@ the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadma This is due to lack of support in Influxdb 2.x API for our approach. Examples of selectors: + ```bash - # get the complete time-series - /demo/example/**?_time=[..] +# get the complete time-series +/demo/example/**?_time=[..] - # get points within a fixed date interval - /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] +# get points within a fixed date interval +/demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] - # get points within a relative date interval - /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] +# get points within a relative date interval +/demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format - ------------------------------- + ## How to install it To install the latest release of this backend library, you can do as follows: @@ -252,9 +271,10 @@ To install the latest release of this backend library, you 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 +- [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) @@ -269,8 +289,8 @@ 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. @@ -278,7 +298,7 @@ sudo apt install zenoh-backend-influxdb-v1 At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash -$ rustup update +rustup update ``` > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be @@ -287,39 +307,49 @@ Otherwise, incompatibilities in memory mapping of shared types between `zenohd` To know the Rust version you're `zenohd` has been built with, use the `--version` option. -### Example with a downloaded version: +### Example with a downloaded version + ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` + Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: ```bash -$ rustup default 1.72.0 +rustup default 1.72.0 ``` And edit the update `Cargo.toml` file to make all 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 +cargo build --release --all-targets -p zenoh-backend-influxdb-v1 ``` + You can build both the versions as well: + ```bash -$ cargo build --release --all-targets +cargo build --release --all-targets ``` ======= -### Example with a version built from sources: + +### Example with a version built from sources + ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` + Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: + - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) @@ -328,10 +358,11 @@ And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: ```bash -$ rustup default 1.72.0 +rustup default 1.72.0 ``` And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: + ```bash -$ cargo update -p zenoh --precise 9f7a37ee +cargo update -p zenoh --precise 9f7a37ee ``` diff --git a/v2/README.md b/v2/README.md index e73c3ec..ac90442 100644 --- a/v2/README.md +++ b/v2/README.md @@ -15,6 +15,7 @@ Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. ------------------------------- + # InfluxDB backend In Zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the @@ -25,104 +26,112 @@ This backend relies on an [InfluxDB](https://www.influxdata.com/products/influxd to implement the 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: **Install latest release:** see [below](#how-to-install-it) -:point_right: **Build "main" branch:** see [below](#How-to-build-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: + +## :warning: Documentation for previous 0.5 versions + The following documentation related to the version currently in development in "main" branch: 0.6.x. For previous versions see the README and code of the corresponding tagged version: - - [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) - - [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.8#readme) + +- [0.5.0-beta.9](https://github.com/eclipse-zenoh/zenoh-backend-influxdb/tree/0.5.0-beta.9#readme) +- [0.5.0-beta.8](https://github.com/eclipse-zenoh/zenoh-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 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" - } +- 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" - } + } + }, + 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 } - } + } + }, + // Optionally, add the REST plugin + rest: { http_port: 8000 } } - ``` - - Run the zenoh router with: - `zenohd -c zenoh.json5` + } + ``` + +- Run the zenoh router with: + `zenohd -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` +- 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 @@ -148,28 +157,33 @@ Alternatively, you can test running both the zenoh router and the InfluxDB servi --> ------------------------------- + ## 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) +- **`"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)* + _(the value doesn't matter, only the property existence is checked)_ - **`"on_closure"`** (optional, string) : the strategy to use when the Storage is removed. There are 3 options: - - *unset* or `"do_nothing"`: the database remains untouched (this is the default behaviour) + - _unset_ or `"do_nothing"`: the database remains untouched (this is the 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. @@ -178,9 +192,11 @@ Storages relying on a `influxdb2` backed volume may have additional configuratio - **`"token"`** (optional, string) : an InfluxDB access token, usually [non-admin](https://docs.influxdata.com/influxdb/cloud/admin/tokens/#readwrite-token). It will be used to read/write points in the database on GET/PUT/DELETE zenoh operations. ------------------------------- + ## **Behaviour of the backend** ### Mapping to InfluxDB concepts + Each **storage** will map to an InfluxDB **database**. Each **key** to store will map to an InfluxDB [**measurement**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#measurement) @@ -188,18 +204,21 @@ named with the key stripped from the `"strip_prefix"` property (see below). Each **key/value** put into the storage will map to an InfluxDB [**point**](https://docs.influxdata.com/influxdb/v1.8/concepts/key_concepts/#point) reusing the timestamp set by zenoh (but with a precision of nanoseconds). The fileds and tags of the point is are the following: - - `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) - - `"timestamp"` field: the original zenoh timestamp - - `"encoding"` field: the value's encoding flag - - `"base64"` field: a boolean indicating if the value is encoded in base64 - - `"value"`field: the value as a string, possibly encoded in base64 for binary values. + +- `"kind"` tag: the zenoh change kind (`"PUT"` for a value that have been put, or `"DEL"` to mark the deletion of the key) +- `"timestamp"` field: the original zenoh timestamp +- `"encoding"` field: the value's encoding flag +- `"base64"` field: a boolean indicating if the value is encoded in base64 +- `"value"`field: the value as a string, possibly encoded in base64 for binary values. ### Behaviour on deletion + On deletion of a key, all points with a timestamp before the deletion message are deleted. A point with `"kind"="DEL`" is inserted (to avoid re-insertion of points with an older timestamp in case of un-ordered messages). In v1, zenoh used to drop the measurement corresponding to the deleted key is dropped if it still contains no points after 5secs. However, influxdb 2.x doesn't support this feature. ### Behaviour on GET + On GET operations, by default the storage returns only the latest point for each key/measurement. This is to be coherent with other backends technologies that only store 1 value per-key. If you want to get time-series as a result of a GET operation, you need to specify a time range via @@ -209,21 +228,22 @@ the `"_time"`argument in your [Selector](https://github.com/eclipse-zenoh/roadma This is due to lack of support in Influxdb 2.x API for our approach. Examples of selectors: + ```bash - # get the complete time-series - /demo/example/**?_time=[..] +# get the complete time-series +/demo/example/**?_time=[..] - # get points within a fixed date interval - /demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] +# get points within a fixed date interval +/demo/example/influxdb/**?_time=[2020-01-01T00:00:00Z..2020-01-02T12:00:00.000000000Z] - # get points within a relative date interval - /demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] +# get points within a relative date interval +/demo/example/influxdb/**?_time=[now(-2d)..now(-1d)] ``` See the [`"_time"` RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Selectors/_time.md) for a complete description of the time range format - ------------------------------- + ## How to install it To install the latest release of this backend library, you can do as follows: @@ -231,9 +251,10 @@ To install the latest release of this backend library, you 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 +- [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) @@ -248,8 +269,8 @@ 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. @@ -257,7 +278,7 @@ sudo apt install zenoh-backend-influxdb-v2 At first, install [Cargo and Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). If you already have the Rust toolchain installed, make sure it is up-to-date with: ```bash -$ rustup update +rustup update ``` > :warning: **WARNING** :warning: : As Rust doesn't have a stable ABI, the backend library should be @@ -266,39 +287,49 @@ Otherwise, incompatibilities in memory mapping of shared types between `zenohd` To know the Rust version you're `zenohd` has been built with, use the `--version` option. -### Example with a downloaded version: +### Example with a downloaded version + ```bash $ zenohd --version The zenoh router v0.10.0-rc built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` + Here, `zenohd` is version `0.10.0-rc` has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: ```bash -$ rustup default 1.72.0 +rustup default 1.72.0 ``` And edit the update `Cargo.toml` file to make all 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 +cargo build --release --all-targets -p zenoh-backend-influxdb-v2 ``` + You can build both the versions as well: + ```bash -$ cargo build --release --all-targets +cargo build --release --all-targets ``` ======= -### Example with a version built from sources: + +### Example with a version built from sources + ```bash $ zenohd --version The zenoh router v0.11.0-dev-37-g9f7a37ee built with rustc 1.72.0 (5680fa18f 2023-08-23) ``` + Here, `zenohd` version is `v0.11.0-dev-37-g9f7a37ee` where: + - `v0.11.0-dev` means it's a development version for the future `v0.11.0` release - `-37`means there have been 37 commits since the tag `0.11.0-dev` marking the begining of developments for this future version - `-g9f7a37ee` indicates the commit number of sources: `9f7a37ee` (the `g` prefix just meaning "git" shall be ignored) @@ -307,10 +338,11 @@ And it has been built with the rustc version `1.72.0`. Install and use this same toolchain with the following command: ```bash -$ rustup default 1.72.0 +rustup default 1.72.0 ``` And update all the `zenoh` dependencies in `Cargo.lock` to use the commit id: + ```bash -$ cargo update -p zenoh --precise 9f7a37ee +cargo update -p zenoh --precise 9f7a37ee ```