This document provides an overview of Zenoh, an open-source distributed data-centric middleware. It summarizes Zenoh's key features including pub/sub, storage/query, compute capabilities and how these can be used in peer-to-peer, routed, and geo-distributed communication patterns. It also describes how to install and use Zenoh in Python and Docker, configure routers and backends, and interact with the system using its REST API.
3. in Python
Requires Python 3.6 minimum.
Latest version (stable):
• Available on pypi.org (https://pypi.org/project/eclipse-zenoh)
• Binary wheels for x86_64, i686 and aarch64
• For other platforms: source distribution requiring Rust toolchain (https://www.rust-lang.org/tools/install)
pip install eclipse-zenoh
Version in development (master):
• https://github.com/eclipse-zenoh/zenoh-python
• Requires Rust toolchain (https://www.rust-lang.org/tools/install)
pip install https://github.com/eclipse-zenoh/zenoh-python/zipball/master
Code examples:
• https://github.com/eclipse-zenoh/zenoh-python/tree/master/examples/zenoh
4. router - in Docker
Latest version (stable):
docker pull eclipse/zenoh:latest
Version in development (master):
docker pull eclipse/zenoh:master
Usage:
docker run --init eclipse/zenoh --help
docker run --init -p 7447:7447/tcp -p 7447:7447/udp -p 8000:8000/tcp eclipse/zenoh
5. router - native
Latest version (stable):
• https://download.eclipse.org/zenoh/zenoh/latest
• Files: eclipse-zenoh-<version>-<platform>.tgz (or .zip)
Version in development (master):
• https://download.eclipse.org/zenoh/zenoh/master
• Files: eclipse-zenoh-<version>-<platform>.tgz (or .zip)
zenohd --help
RUST_LOG=info zenohd
Usage:
13. pub/sub in Python
Publications are made via the put() operation:
• See https://github.com/eclipse-zenoh/zenoh-python/blob/master/examples/zenoh/z_put.py
from zenoh import Zenoh
z = Zenoh({})
workspace = z.workspace()
workspace.put("/demo/example/hi", "Hello World!")
Subscriptions are made via the subscribe() operation:
• See https://github.com/eclipse-zenoh/zenoh-python/blob/master/examples/zenoh/z_sub.py
from zenoh import Zenoh, ChangeKind
def listener(change):
print("{} : {} (encoding: {} , timestamp: {})".format(change.path,
"DELETED" if change.kind == ChangeKind.DELETE else change.value.get_content(),
"none" if change.kind == ChangeKind.DELETE else change.value.encoding_descr(),
change.timestamp))
z = Zenoh({})
workspace = z.workspace()
workspace.subscribe("/demo/example/**", listener)
14. Value types and encodings
zenoh supports different value types.
Each has an encoding described by its mime-type:
from zenoh import Zenoh
import json
z = Zenoh({})
workspace = z.workspace()
# - String
workspace.put('/demo/example/String', 'Hello World!')
# - Integer
workspace.put('/demo/example/Integer', 3)
# - Float
workspace.put('/demo/example/Float', 3.14)
# - Properties (as a Dictionary with str only)
workspace.put('/demo/example/Properties', {'p1': 'v1', 'p2': 'v2'})
# - Json (str format)
workspace.put('/demo/example/Json',
Value.Json(json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])))
# - Raw ('application/octet-stream' encoding by default)
workspace.put('/demo/example/Raw', b'x48x69x21')
# - Custom
workspace.put('/demo/example/Custom',
Value.Custom('my_encoding', b'x48x69x21'))
17. pub/store/query in Python
Deletions from storage are made via the delete() operation:
• See https://github.com/eclipse-zenoh/zenoh-python/blob/master/examples/zenoh/z_delete.py
from zenoh import Zenoh
z = Zenoh({})
workspace = z.workspace()
workspace.delete("/demo/example/hi")
Publications are made via the put() operation (seen previously).
Queries are made via the get() operation:
• See https://github.com/eclipse-zenoh/zenoh-python/blob/master/examples/zenoh/z_get.py
from zenoh import Zenoh
z = Zenoh({})
workspace = z.workspace()
for data in workspace.get("/demo/example/**"):
print("{} : {} (encoding: {} , timestamp: {})".format(
data.path, data.value.get_content(), data.value.encoding_descr(), data.timestamp))
20. Compute/query in Python
Queries are made via the get() operation (seen previously).
Compute are declared via the register_eval() operation:
• See https://github.com/eclipse-zenoh/zenoh-python/blob/master/examples/zenoh/z_eval.py
import datetime
from zenoh import Zenoh
def eval_callback(get_request):
get_request.reply("/demo/example/eval", "It's {}".format(datetime.datetime.now().time()))
z = Zenoh({})
workspace = z.workspace()
workspace.register_eval("/demo/example/eval", eval_callback)
22. REST API
Implemented as a plugin. Default port: 8080.
The zenoh put/get/delete operations map to the PUT/GET/DELETE HTTP methods.
Example using the curl command:
# Put a string value in /demo/example/test
curl -X PUT -d 'Hello World!' http://localhost:8000/demo/example/test
# Put a JSON value in /demo/example/json
curl -X PUT -H "Content-Type: application/json" -d '{"value": "Hello World!"}' http://localhost:8000/demo/example/test
# Put a Properties value in /demo/example/props
curl -X PUT -H 'content-type:application/properties' -d 'k1=v1;k2=v2' http://localhost:8000/demo/example/props
# Get the keys/values matching /demo/**
curl http://localhost:8000/demo/**
# Get the keys/values matching /demo/example/*eval (i.e. the zenoh eval examples)
# with property name=Bob
curl http://localhost:8000/demo/example/*eval?(name=Bob)
# Delete key/value /demo/example/test
curl -X DELETE http://localhost:8000/demo/example/test
24. Backends
A zenoh backend is:
• a library, loaded on demand by the zenoh router (name: libzbackend_<id>.so)
• a factory for zenoh storages
• leveraging a speci
fi
c technology to implement storages
Existing backends:
• In-memory: built-in in zenoh router
• File system:
• https://github.com/eclipse-zenoh/zenoh-backend-
fi
lesystem
• RocksDB:
• https://github.com/eclipse-zenoh/zenoh-backend-rocksdb
• In
fl
uxDB:
• https://github.com/eclipse-zenoh/zenoh-backend-in
fl
uxdb
25. Admin space
zenoh admin space:
•A zenoh key/value space with under /@/**
•Addressable via zenoh APIs
using put/get/delete operations
•Each router addressable via its ID, or the "local"
keyword for the router an API is connected to
/@/router/1a2b3c.../plugin/storages
/backend
/memory /rocksdb /<beid>
/storage /storage
/s2
/s1
...
...
/storage
/db2
/db1 ...
# Get local router's info
curl http://localhost:8000/@/router/local
# Get all routers' of the system
curl http://localhost:8000/@/router/*
# Get local router's storages info
curl http://localhost:8000/@/router/local/**/storages/**
Examples using the REST API:
26. Backends/storages management
Examples using the REST API:
# Add a memory storage
curl -X PUT -H 'content-type:application/properties' -d 'path_expr=/demo/test/**'
http://localhost:8000/@/router/local/plugin/storages/backend/memory/storage/my-test
# Add a FileSystem backend (assuming libzbackend_fs.so is available)
curl -X PUT -H 'content-type:application/properties'
http://localhost:8000/@/router/local/plugin/storages/backend/fs
# Add a FileSystem storage
curl -X PUT -H 'content-type:application/properties' -d 'path_expr=/demo/example/**;path_prefix=/demo/example;dir=test'
http://localhost:8000/@/router/local/plugin/storages/backend/fs/storage/my-test
# Add an InfluxDB backend (assuming libzbackend_influxdb.so is available and InfluxDB running at http://localhost:8086)
curl -X PUT -H 'content-type:application/properties' -d 'url=http://localhost:8086'
http://localhost:8000/@/router/local/plugin/storages/backend/influxdb
# Add an InfluxDB storage using the database named "zenoh-example"
curl -X PUT -H 'content-type:application/properties' -d 'path_expr=/demo/example/**;db=zenoh-example'
http://localhost:8000/@/router/local/plugin/storages/backend/influxdb/storage/my-test
28. Plugins
A zenoh plugin is
• a library, loaded at start-up by the zenoh router (name: libzplugin_<id>.so)
• similar to zenoh application using the zenoh APIs (in RUST)
• using the router's runtime => no transport overhead
Existing plugins:
• REST plugin (packaged with zenoh deliverable)
• Storages plugin (packaged with zenoh deliverable)
• WebServer plugin:
• https://github.com/eclipse-zenoh/zenoh-plugin-webserver
• DDS plugin:
• https://github.com/eclipse-zenoh/zenoh-plugin-dds