title | keywords | tags | permalink | ||
---|---|---|---|---|---|
MQTT 3.1.1 protocol binding |
binding, protocol, mqtt |
|
connectivity-protocol-bindings-mqtt.html |
When MQTT messages are sent in Ditto Protocol,
the payload should be UTF-8
encoded strings.
If messages which are not in Ditto Protocol should be processed, a payload mapping must be configured for the connection in order to transform the messages.
MQTT 3.1.1 messages have no application headers. Transmission-relevant properties are set in the
"headers"
field as a part of Ditto protocol messages in the
payload.
These properties are supported:
correlation-id
: For correlating request messages and events. Twin events have the correlation IDs of Twin commands that produced them.reply-to
: The value should be an MQTT topic. If a command sets the headerreply-to
, then its response is published at the topic equal to the header value.
For an MQTT connection:
- Source
"addresses"
are MQTT topics to subscribe to. Wildcards+
and#
are allowed. "authorizationContext"
may not contain placeholders{%raw%}{{ header:<header-name> }}{%endraw%}
as MQTT 3.1.1 has no application headers.- The optional field
"qos"
sets the maximum Quality of Service to request when subscribing for messages. Its value can be0
for at-most-once delivery,1
for at-least-once delivery and2
for exactly-once delivery. The default value is2
(exactly-once). Support of any Quality of Service depends on the external MQTT broker; AWS IoT for example does not acknowledge subscriptions withqos=2
.
{
"addresses": [
"<mqtt_topic>",
"..."
],
"authorizationContext": ["ditto:inbound-auth-subject", "..."],
"qos": 2
}
{% include_relative connectivity-enforcement.md %}
The following placeholders are available for the input
field:
Placeholder | Description | Example |
---|---|---|
{%raw%}{{ source:address }}{%endraw%} |
The topic on which the message was received. | devices/sensors/temperature1 |
Assuming a device temperature1
publishes its telemetry data to an MQTT broker on topic devices/sensors/temperature1
.
The MQTT broker verifies that no other device is allowed to publish on this topic. To enforce that the device can
only send data to the Thing sensors:temperature1
the following enforcement configuration can be used:
{
"enforcement": {
"input": "{%raw%}{{ source:address }}{%endraw%}",
"filters": [ "{%raw%}devices/{{ thing:namespace }}/{{ thing:name }}{%endraw%}" ]
},
"addresses": [ "devices/sensors/#" ],
"authorizationContext": ["ditto:inbound-auth-subject", "..."]
}
For an MQTT connection, the target address is the MQTT topic to publish events and messages to. The target address may contain placeholders; see placeholders section for more information.
Further, "topics"
is a list of strings, each list entry representing a subscription of
Ditto protocol topics.
Outbound messages are published to the configured target address if one of the subjects in "authorizationContext"
have READ permission on the Thing that is associated with a message.
The additional field "qos"
sets the Quality of Service with which messages are published.
Its value can be 0
for at-most-once delivery, 1
for at-least-once delivery and 2
for exactly-once delivery.
Support of any Quality of Service depends on the external MQTT broker.
The default value is 0
(at-most-once).
{
"address": "mqtt/topic/of/my/device/{%raw%}{{ thing:id }}{%endraw%}",
"topics": [
"_/_/things/twin/events",
"_/_/things/live/messages"
],
"authorizationContext": ["ditto:outbound-auth-subject", "..."],
"qos": 0
}
In order to only consume specific events like described in change notifications, the
following parameters can additionally be provided when specifying the topics
of a target:
Description | Topic | Filter by namespaces | Filter by RQL expression |
---|---|---|---|
Subscribe for events/change notifications | _/_/things/twin/events |
yes | yes |
Subscribe for messages | _/_/things/live/messages |
yes | |
Subscribe for live commands | _/_/things/live/commands |
yes | |
Subscribe for live events | _/_/things/live/events |
yes | yes |
The parameters are specified similar to HTTP query parameters, the first one separated with a ?
and all following ones
with &
. You have to URL encode the filter values before using them in a configuration.
For example this way the connection session would register for all events in the namespace org.eclipse.ditto
and which
would match an attribute "counter" to be greater than 42. Additionally it would subscribe to messages in the namespace
org.eclipse.ditto
:
{
"address": "eclipse-ditto-sandbox/{%raw%}{{ thing:id }}{%endraw%}",
"topics": [
"_/_/things/twin/events?namespaces=org.eclipse.ditto&filter=gt(attributes/counter,42)",
"_/_/things/live/messages?namespaces=org.eclipse.ditto"
],
"authorizationContext": ["ditto:outbound-auth-subject", "..."]
}
Ditto's Connectivity service is responsible for creating new and managing existing connections.
This can be done dynamically at runtime without the need to restart any microservice using a Ditto DevOps command.
Example
Connection configuration to create a new MQTT connection:
{
"id": "mqtt-example-connection-123",
"connectionType": "mqtt",
"connectionStatus": "open",
"failoverEnabled": true,
"uri": "tcp://test.mosquitto.org:1883",
"sources": [
{
"addresses": [
"eclipse-ditto-sandbox/#"
],
"authorizationContext": ["ditto:inbound-auth-subject"],
"qos": 0,
"filters": []
}
],
"targets": [
{
"address": "eclipse-ditto-sandbox/{%raw%}{{ thing:id }}{%endraw%}",
"topics": [
"_/_/things/twin/events"
],
"authorizationContext": ["ditto:outbound-auth-subject"],
"qos": 0
}
]
}
Messages consumed via the MQTT binding are treated similar to the WebSocket binding, meaning that the messages are expected to be Ditto Protocol messages serialized as UTF-8-coded JSON (as shown for example in the protocol examples). If your payload does not conform to the Ditto Protocol or uses any character set other than UTF-8, you can configure a custom payload mapping.
Ditto supports certificate-based authentication for MQTT connections. Consult Certificates for Transport Layer Security for how to set it up.
Here is an example MQTT connection that checks the broker certificate and authenticates by a client certificate.
{
"id": "mqtt-example-connection-124",
"connectionType": "mqtt",
"connectionStatus": "open",
"failoverEnabled": true,
"uri": "ssl://test.mosquitto.org:8884",
"validateCertificates": true,
"ca": "-----BEGIN CERTIFICATE-----\n<test.mosquitto.org certificate>\n-----END CERTIFICATE-----",
"credentials": {
"type": "client-cert",
"cert": "-----BEGIN CERTIFICATE-----\n<signed client certificate>\n-----END CERTIFICATE-----",
"key": "-----BEGIN PRIVATE KEY-----\n<client private key>\n-----END PRIVATE KEY-----"
},
"sources": [
{
"addresses": [
"eclipse-ditto-sandbox/#"
],
"authorizationContext": ["ditto:inbound-auth-subject"],
"qos": 0,
"filters": []
}
],
"targets": [
{
"address": "eclipse-ditto-sandbox/{%raw%}{{ thing:id }}{%endraw%}",
"topics": [
"_/_/things/twin/events"
],
"authorizationContext": ["ditto:outbound-auth-subject"],
"qos": 0
}
]
}