From e14c6782a95aaa009d33b9a6b72194cbaebd39ff Mon Sep 17 00:00:00 2001 From: Jacob Brunson Date: Mon, 4 Dec 2023 14:54:24 -0700 Subject: [PATCH] feat: add mqtt v5 specific bindings to mqtt (#201) Co-authored-by: Sergio Moya <1083296+smoya@users.noreply.github.com>%0ACo-authored-by: Khuda Dad Nomani <32505158+KhudaDad414@users.noreply.github.com>%0ACo-authored-by: Lukasz Gornicki --- mqtt/README.md | 126 ++++++++++++++++++++++++------- mqtt/json_schemas/message.json | 53 ++++++++++++- mqtt/json_schemas/operation.json | 22 +++++- mqtt/json_schemas/server.json | 39 +++++++++- mqtt5/README.md | 2 + 5 files changed, 206 insertions(+), 36 deletions(-) diff --git a/mqtt/README.md b/mqtt/README.md index 0161fdb9..7f6d7f9e 100644 --- a/mqtt/README.md +++ b/mqtt/README.md @@ -2,11 +2,13 @@ This document defines how to describe MQTT-specific information on AsyncAPI. +It applies to all versions of MQTT, although specific binding fields may only apply to particular versions. + ## Version -Current version is `0.1.0`. +Current version is `0.2.0`. @@ -17,21 +19,23 @@ This object contains information about the server representation in MQTT. ##### Fixed Fields -Field Name | Type | Description ----|:---:|--- -`clientId` | string | The client identifier. -`cleanSession` | boolean | Whether to create a persistent connection or not. When `false`, the connection will be persistent. -`lastWill` | object | Last Will and Testament configuration. -`lastWill.topic` | string | The topic where the Last Will and Testament message will be sent. -`lastWill.qos` | integer | Defines how hard the broker/client will try to ensure that the Last Will and Testament message is received. Its value MUST be either 0, 1 or 2. -`lastWill.message` | string | Last Will message. -`lastWill.retain` | boolean | Whether the broker should retain the Last Will and Testament message or not. -`keepAlive` | integer | Interval in seconds of the longest period of time the broker and the client can endure without sending a message. -`bindingVersion` | string | The version of this binding. If omitted, "latest" MUST be assumed. +Field Name | Type | MQTT Versions | Description +---|:---:|:---:|---| +`clientId` | string | 3, 5 | The client identifier. +`cleanSession` | boolean | 3, 5 | Whether to create a persistent connection or not. When `false`, the connection will be persistent. This is called **clean start** in MQTTv5. +`lastWill` | object | 3, 5 | Last Will and Testament configuration. `topic`, `qos`, `message` and `retain` are properties of this object as shown below. +`lastWill.topic` | string | 3, 5 | The topic where the Last Will and Testament message will be sent. +`lastWill.qos` | integer | 3, 5 | Defines how hard the broker/client will try to ensure that the Last Will and Testament message is received. Its value MUST be either 0, 1 or 2. +`lastWill.message` | string | 3, 5 | Last Will message. +`lastWill.retain` | boolean | 3, 5 | Whether the broker should retain the Last Will and Testament message or not. +`keepAlive` | integer | 3, 5 | Interval in seconds of the longest period of time the broker and the client can endure without sending a message. +`sessionExpiryInterval` | integer \| [Schema Object][schemaObject] \| [Reference Object](referenceObject) | 5 | Interval in seconds or a *Schema Object* containing the definition of the interval. The broker maintains a session for a disconnected client until this interval expires. +`maximumPacketSize` | integer \| [Schema Object][schemaObject] \| [Reference Object](referenceObject) | 5 | Number of bytes or a *Schema Object* representing the maximum packet size the client is willing to accept. +`bindingVersion` | string | | The version of this binding. If omitted, "latest" MUST be assumed. | This object MUST contain only the properties defined above. -##### Example +##### Examples ```yaml servers: @@ -46,9 +50,24 @@ servers: message: Guest gone offline. retain: false keepAlive: 60 - bindingVersion: 0.1.0 + sessionExpiryInterval: 600 + maximumPacketSize: 1200 + bindingVersion: 0.2.0 +``` +```yaml +servers: + production: + bindings: + mqtt: + sessionExpiryInterval: + type: integer + minimum: 30 + maximum: 1200 + maximumPacketSize: + type: integer + minimum: 256 + bindingVersion: 0.2.0 ``` - @@ -57,7 +76,6 @@ servers: This object MUST NOT contain any properties. Its name is reserved for future use. - ## Operation Binding Object @@ -66,15 +84,16 @@ This object contains information about the operation representation in MQTT. ##### Fixed Fields -Field Name | Type | Applies To | Description ----|:---:|:---:|--- -`qos` | integer | Publish, Subscribe | Defines the Quality of Service (QoS) levels for the message flow between client and server. Its value MUST be either 0 (At most once delivery), 1 (At least once delivery), or 2 (Exactly once delivery). -`retain` | boolean | Publish, Subscribe | Whether the broker should retain the message or not. -`bindingVersion` | string | Publish, Subscribe | The version of this binding. If omitted, "latest" MUST be assumed. +Field Name | Type | Applies To | MQTT Versions | Description +---|:---:|:---:|:---:|--- +`qos` | integer | Publish, Subscribe | 3, 5 | Defines the Quality of Service (QoS) levels for the message flow between client and server. Its value MUST be either 0 (At most once delivery), 1 (At least once delivery), or 2 (Exactly once delivery). +`retain` | boolean | Publish | 3, 5 | Whether the broker should retain the message or not. +`messageExpiryInterval` | integer \| [Schema Object][schemaObject] \| [Reference Object](referenceObject)| Publish | 5 | Interval in seconds or a *Schema Object* containing the definition of the lifetime of the message. +`bindingVersion` | string | | | The version of this binding. If omitted, "latest" MUST be assumed. This object MUST contain only the properties defined above. -##### Example +##### Examples ```yaml channels: @@ -84,9 +103,30 @@ channels: mqtt: qos: 2 retain: true - bindingVersion: 0.1.0 + messageExpiryInterval: 60 + bindingVersion: 0.2.0 +``` +```yaml +channels: + user/signup: + publish: + bindings: + mqtt: + messageExpiryInterval: + type: integer + minimum: 30 + maximum: 300 + bindingVersion: 0.2.0 +``` +```yaml +channels: + user/signup: + subscribe: + bindings: + mqtt: + qos: 2 + bindingVersion: 0.2.0 ``` - @@ -96,12 +136,31 @@ This object contains information about the message representation in MQTT. ##### Fixed Fields -Field Name | Type | Description ----|:---:|--- -`bindingVersion` | string | The version of this binding. If omitted, "latest" MUST be assumed. +Field Name | Type | MQTT Versions | Description +---|:---:|:---:|--- +`payloadFormatIndicator` | integer | 5 | Either: **0** (zero): Indicates that the payload is unspecified bytes, or **1**: Indicates that the payload is UTF-8 encoded character data. | +`correlationData` | [Schema Object][schemaObject] \| [Reference Object](referenceObject) | 5 | Correlation Data is used by the sender of the request message to identify which request the response message is for when it is received. +`contentType` | string | 5 | String describing the content type of the message payload. This should not conflict with the `contentType` field of the associated AsyncAPI Message object. +`responseTopic` | URI string \| [Schema Object][schemaObject] \| [Reference Object](referenceObject) | 5 | The topic (channel URI) for a response message. +`bindingVersion` | string | | The version of this binding. If omitted, "latest" MUST be assumed. This object MUST contain only the properties defined above. +##### Examples + +```yaml +channels: + user/signup: + subscribe: + message: + bindings: + mqtt: + contentType: "application/json" + correlationData: + type: string + format: uuid + bindingVersion: 0.2.0 +``` ```yaml channels: user/signup: @@ -109,5 +168,16 @@ channels: message: bindings: mqtt: - bindingVersion: 0.1.0 + payloadFormatIndicator: 1 + contentType: "application/json" + correlationData: + type: string + format: uuid + responseTopic: + type: string + pattern: "response/client/([a-z1-9]+)" + bindingVersion: 0.2.0 ``` + +[schemaObject]: https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#schemaObject +[referenceObject]: https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#referenceObject diff --git a/mqtt/json_schemas/message.json b/mqtt/json_schemas/message.json index 7f9b1057..dd97488e 100644 --- a/mqtt/json_schemas/message.json +++ b/mqtt/json_schemas/message.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://asyncapi.com/bindings/mqtt/message.json", - "title": "Operation Schema", + "title": "Message Schema", "description": "This object contains information about the message representation in MQTT.", "type": "object", "additionalProperties": false, @@ -11,17 +11,64 @@ } }, "properties": { + "payloadFormatIndicator": { + "type": "integer", + "enum": [0, 1], + "description": "1 indicates that the payload is UTF-8 encoded character data. 0 indicates that the payload format is unspecified.", + "default": 0 + }, + "correlationData": { + "oneOf": [ + { + "$ref": "https://asyncapi.com/definitions/2.6.0/schema.json" + }, + { + "$ref": "https://asyncapi.com/definitions/2.6.0/Reference.json" + } + ], + "description": "Correlation Data is used by the sender of the request message to identify which request the response message is for when it is received." + }, + "contentType": { + "type": "string", + "description": "String describing the content type of the message payload. This should not conflict with the contentType field of the associated AsyncAPI Message object." + }, + "responseTopic": { + "oneOf": [ + { + "type": "string", + "format": "uri-template", + "minLength": 1 + }, + { + "$ref": "https://asyncapi.com/definitions/2.6.0/schema.json" + }, + { + "$ref": "https://asyncapi.com/definitions/2.6.0/Reference.json" + } + ], + "description": "The topic (channel URI) to be used for a response message." + }, + "bindingVersion": { "type": "string", "enum": [ - "0.1.0" + "0.2.0" ], "description": "The version of this binding. If omitted, 'latest' MUST be assumed." } }, "examples": [ { - "bindingVersion": "0.1.0" + "bindingVersion": "0.2.0" + }, + { + "contentType": "application/json", + "correlationData": { + "type": "string", + "format": "uuid" + }, + "responseTopic": "application/responses", + "bindingVersion": "0.2.0" } ] } diff --git a/mqtt/json_schemas/operation.json b/mqtt/json_schemas/operation.json index eb2f6aa5..fc1b66b8 100644 --- a/mqtt/json_schemas/operation.json +++ b/mqtt/json_schemas/operation.json @@ -13,16 +13,33 @@ "properties": { "qos": { "type": "integer", + "enum": [0,1,2], "description": "Defines the Quality of Service (QoS) levels for the message flow between client and server. Its value MUST be either 0 (At most once delivery), 1 (At least once delivery), or 2 (Exactly once delivery)." }, "retain": { "type": "boolean", "description": "Whether the broker should retain the message or not." }, + "messageExpiryInterval": { + "oneOf": [ + { + "type": "integer", + "minimum": 0, + "maximum": 4294967295 + }, + { + "$ref": "https://asyncapi.com/definitions/2.6.0/schema.json" + }, + { + "$ref": "https://asyncapi.com/definitions/2.6.0/Reference.json" + } + ], + "description": "Lifetime of the message in seconds" + }, "bindingVersion": { "type": "string", "enum": [ - "0.1.0" + "0.2.0" ], "description": "The version of this binding. If omitted, 'latest' MUST be assumed." } @@ -31,7 +48,8 @@ { "qos": 2, "retain": true, - "bindingVersion": "0.1.0" + "messageExpiryInterval": 60, + "bindingVersion": "0.2.0" } ] } diff --git a/mqtt/json_schemas/server.json b/mqtt/json_schemas/server.json index 31247ac1..fd413df3 100644 --- a/mqtt/json_schemas/server.json +++ b/mqtt/json_schemas/server.json @@ -18,7 +18,7 @@ }, "cleanSession": { "type": "boolean", - "description": "Whether to create a persistent connection or not. When 'false', the connection will be persistent." + "description": "Whether to create a persistent connection or not. When 'false', the connection will be persistent. This is called clean start in MQTTv5." }, "lastWill": { "type": "object", @@ -47,10 +47,41 @@ "type": "integer", "description": "Interval in seconds of the longest period of time the broker and the client can endure without sending a message." }, + "sessionExpiryInterval": { + "oneOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "$ref": "https://asyncapi.com/definitions/2.6.0/schema.json" + }, + { + "$ref": "https://asyncapi.com/definitions/2.6.0/Reference.json" + } + ], + "description": "Interval time in seconds or a Schema Object containing the definition of the interval. The broker maintains a session for a disconnected client until this interval expires." + }, + "maximumPacketSize": { + "oneOf": [ + { + "type": "integer", + "minimum": 1, + "maximum": 4294967295 + }, + { + "$ref": "https://asyncapi.com/definitions/2.6.0/schema.json" + }, + { + "$ref": "https://asyncapi.com/definitions/2.6.0/Reference.json" + } + ], + "description": "Number of bytes or a Schema Object representing the Maximum Packet Size the Client is willing to accept." + }, "bindingVersion": { "type": "string", "enum": [ - "0.1.0" + "0.2.0" ], "description": "The version of this binding. If omitted, 'latest' MUST be assumed." } @@ -66,7 +97,9 @@ "retain": false }, "keepAlive": 60, - "bindingVersion": "0.1.0" + "sessionExpiryInterval": 120, + "maximumPacketSize": 1024, + "bindingVersion": "0.2.0" } ] } diff --git a/mqtt5/README.md b/mqtt5/README.md index 3e794ba0..5bda5024 100644 --- a/mqtt5/README.md +++ b/mqtt5/README.md @@ -2,6 +2,8 @@ This document defines how to describe MQTT 5-specific information on AsyncAPI. +# **Deprecation Warning**: MQTT version 5 specific bindings are deprecated in favor of [MQTT bindings](../mqtt/README.md) that are not version specific. + ## Version