Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add mqtt v5 specific bindings to mqtt #201

Merged
merged 7 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 98 additions & 28 deletions mqtt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<a name="version"></a>

## Version

Current version is `0.1.0`.
Current version is `0.2.0`.


<a name="server"></a>
Expand All @@ -17,21 +19,23 @@ This object contains information about the server representation in MQTT.

##### Fixed Fields

Field Name | Type | Description
---|:---:|---
<a name="serverBindingObjectClientId"></a>`clientId` | string | The client identifier.
<a name="serverBindingObjectCleanSession"></a>`cleanSession` | boolean | Whether to create a persistent connection or not. When `false`, the connection will be persistent.
<a name="serverBindingObjectLastWill"></a>`lastWill` | object | Last Will and Testament configuration.
<a name="serverBindingObjectLastWillTopic"></a>`lastWill.topic` | string | The topic where the Last Will and Testament message will be sent.
<a name="serverBindingObjectLastWillQoS"></a>`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.
<a name="serverBindingObjectLastWillMessage"></a>`lastWill.message` | string | Last Will message.
<a name="serverBindingObjectLastWillRetain"></a>`lastWill.retain` | boolean | Whether the broker should retain the Last Will and Testament message or not.
<a name="serverBindingObjectKeepAlive"></a>`keepAlive` | integer | Interval in seconds of the longest period of time the broker and the client can endure without sending a message.
<a name="serverBindingObjectBindingVersion"></a>`bindingVersion` | string | The version of this binding. If omitted, "latest" MUST be assumed.
Field Name | Type | MQTT Versions | Description
---|:---:|:---:|---|
<a name="serverBindingObjectClientId"></a>`clientId` | string | 3, 5 | The client identifier.
<a name="serverBindingObjectCleanSession"></a>`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.
<a name="serverBindingObjectLastWill"></a>`lastWill` | object | 3, 5 | Last Will and Testament configuration. `topic`, `qos`, `message` and `retain` are properties of this object as shown below.
<a name="serverBindingObjectLastWillTopic"></a>`lastWill.topic` | string | 3, 5 | The topic where the Last Will and Testament message will be sent.
<a name="serverBindingObjectLastWillQoS"></a>`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.
<a name="serverBindingObjectLastWillMessage"></a>`lastWill.message` | string | 3, 5 | Last Will message.
<a name="serverBindingObjectLastWillRetain"></a>`lastWill.retain` | boolean | 3, 5 | Whether the broker should retain the Last Will and Testament message or not.
<a name="serverBindingObjectKeepAlive"></a>`keepAlive` | integer | 3, 5 | Interval in seconds of the longest period of time the broker and the client can endure without sending a message.
<a name="serverBindingObjectSessionExpiryInterval"></a>`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.
<a name="serverBindingObjectMaximumPacketSize"></a>`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.
<a name="serverBindingObjectBindingVersion"></a>`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:
Expand All @@ -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
```


<a name="channel"></a>

Expand All @@ -57,7 +76,6 @@ servers:
This object MUST NOT contain any properties. Its name is reserved for future use.



<a name="operation"></a>

## Operation Binding Object
Expand All @@ -66,15 +84,16 @@ This object contains information about the operation representation in MQTT.

##### Fixed Fields

Field Name | Type | Applies To | Description
---|:---:|:---:|---
<a name="operationBindingObjectQoS"></a>`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).
<a name="operationBindingObjectRetain"></a>`retain` | boolean | Publish, Subscribe | Whether the broker should retain the message or not.
<a name="operationBindingObjectBindingVersion"></a>`bindingVersion` | string | Publish, Subscribe | The version of this binding. If omitted, "latest" MUST be assumed.
Field Name | Type | Applies To | MQTT Versions | Description
---|:---:|:---:|:---:|---
<a name="operationBindingObjectQoS"></a>`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).
<a name="operationBindingObjectRetain"></a>`retain` | boolean | Publish | 3, 5 | Whether the broker should retain the message or not.
<a name="operationBindingObjectMessageExpiryInterval"></a>`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.
<a name="operationBindingObjectBindingVersion"></a>`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:
Expand All @@ -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
```


<a name="message"></a>

Expand All @@ -96,18 +136,48 @@ This object contains information about the message representation in MQTT.

##### Fixed Fields

Field Name | Type | Description
---|:---:|---
<a name="messageBindingObjectBindingVersion"></a>`bindingVersion` | string | The version of this binding. If omitted, "latest" MUST be assumed.
Field Name | Type | MQTT Versions | Description
---|:---:|:---:|---
<a name="messageBindingObjectPayloadFormatIndicator"></a>`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. |
<a name="messageBindingObjectCorrelationData"></a>`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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this different from the correlation ID? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same as a correlation ID. correlationData is the MQTT term. When this binding property is provided in the spec, it signals that the correlation ID should be provided in the MQTTv5 PUBLISH property designated for such.

I'd love to update the correlation ID runtime expression to indicate that a protocol binding field should be used for the correlation ID.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright 👍

<a name="messageBindingObjectContentType"></a>`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.
Copy link
Member

@jonaslagoni jonaslagoni Aug 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come the contentType of the AsyncAPI Message object is not enough 🤔 Or rather whats the difference?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contentType of the Message object is a requirement of the payload format.

Providing a contentType message binding requires that the MQTTv5 PUBLISH packet include the "Content Type" property.

If we were talking HTTP, it would be the difference between requiring the payload to be JSON and requiring the HTTP headers include Content-Type: application/json

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it 👍

<a name="messageBindingObjectResponseTopic"></a>`responseTopic` | URI string \| [Schema Object][schemaObject] \| [Reference Object](referenceObject) | 5 | The topic (channel URI) for a response message.
<a name="messageBindingObjectBindingVersion"></a>`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:
publish:
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
53 changes: 50 additions & 3 deletions mqtt/json_schemas/message.json
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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"
}
]
}
22 changes: 20 additions & 2 deletions mqtt/json_schemas/operation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."
}
Expand All @@ -31,7 +48,8 @@
{
"qos": 2,
"retain": true,
"bindingVersion": "0.1.0"
"messageExpiryInterval": 60,
"bindingVersion": "0.2.0"
}
]
}
39 changes: 36 additions & 3 deletions mqtt/json_schemas/server.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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."
}
Expand All @@ -66,7 +97,9 @@
"retain": false
},
"keepAlive": 60,
"bindingVersion": "0.1.0"
"sessionExpiryInterval": 120,
"maximumPacketSize": 1024,
"bindingVersion": "0.2.0"
}
]
}
2 changes: 2 additions & 0 deletions mqtt5/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<a name="version"></a>

## Version
Expand Down