-
Notifications
You must be signed in to change notification settings - Fork 30
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
MQTT Service private preview user documentation #2695
Open
scmi-c8y
wants to merge
15
commits into
develop
Choose a base branch
from
private-preview/mqtt-service
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+354
−0
Open
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
51accc8
MTM-49410 As a customer I need a MQTT Connect user documentation guide
schmiel-cumulocity d67ca7f
MTM-56190 Rename MQTT Connect to MQTT Service
schmiel-cumulocity 7403f68
MTM-56141 Update MQTT Service documentation with all necessary inform…
schmiel-cumulocity 8eb7904
MTM-58341 Update MQTT Service client usage documentation
schmiel-cumulocity 67ffb4d
MQTT Service user doc - Apply suggestions from code review
a4220d0
MTM-59931 Support for Additional Special Characters in MQTT Topics (#…
55418b0
Apply a recommendation from PM (#2352)
scmi-c8y ad104cf
MTM-58268: Document MQTT service auto topic deletion
abor-c8y c7ec193
MTM-58268: Add section with information about how topic limit works a…
abor-c8y 1ee9666
MTM-58268: Complete sentence for PUBLISH with MQTT3
abor-c8y 355a944
MTM-58268: Improvements to documentation from PR comments
abor-c8y 26e3d06
Merge pull request #2464 from Cumulocity-IoT/feature/MTM-58268/docume…
abor-c8y 0c42bb4
MTM-61476: Add section describing how to use mqtt service error topic…
abor-c8y e5fee62
Merge branch 'private-preview/mqtt-connect' into private-preview/mqtt…
scmi-c8y d6c2a25
MTM-61949: Remove reference to now removed MQTT_SERVICE_ADMIN role (#…
abor-c8y File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
weight: 90 | ||
layout: redirect | ||
title: FAQ | ||
--- | ||
|
||
Q: How to obtain device credential?<br/> | ||
A: MQTT Service does not support a device bootstrap process yet. Instead, follow the [Integration life cycle](/device-integration/mqtt/#integration-life-cycle) | ||
to bootstrap the device and obtain device credentials. Once the device credentials are obtained, ensure that they have `Mqtt Service` `ADMIN` permission. | ||
You can achieve this for all devices by granting this permission to the `devices` global role. | ||
|
||
Q: Does MQTT Service support the SmartREST 2.0 protocol?<br/> | ||
A: Not yet, support for SmartREST 2.0 will be added in the future. | ||
|
||
Q: Why does MQTT Service not use standard MQTT ports 1883 and 8883?<br/> | ||
A: Those ports are already used by {{< product-c8y-iot >}} MQTT. Both endpoints are working together MQTT Service must use different ports. |
178 changes: 178 additions & 0 deletions
178
content/device-integration/mqtt-service-bundle/implementation.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
--- | ||
weight: 20 | ||
title: MQTT protocol implementation | ||
layout: redirect | ||
--- | ||
|
||
This section lists the implementation details for the MQTT Service. The MQTT Service implementation supports MQTT Version 3.1.1, support for 5.0 is planned. | ||
|
||
### Connecting via MQTT {#connecting-via-mqtt} | ||
|
||
MQTT Service is supported via TCP. Use your tenant domain as the URL. | ||
|
||
Available ports: | ||
|
||
| | TCP | | ||
|:-----|:----| | ||
| TLS | 9883 | | ||
| no TLS | 2883 | | ||
|
||
Port 9883 is enabled by default. It currently supports one-way SSL meaning that only the client validates the server certificate to ensure its identity. | ||
The client is authenticated by the server via standard username and password credentials. | ||
To enable port 2883 please contact [Product support](/additional-resources/contacting-support/). | ||
|
||
### Topic {#topic} | ||
|
||
MQTT Service topics are mapped to the Messaging Service subscriptions with identical names, including additional URL encoding. | ||
The Messaging Service subscriptions reliably store the topic messages for asynchronous processing. | ||
The messages stored on these subscriptions can be consumed using a dedicated [Java Client](/device-integration/mqtt-service#java-client). | ||
|
||
#### Topic restrictions {#topic-restrictions} | ||
|
||
MQTT Service does not impose any topic structure. There are just a few topic names which are reserved for historic purposes and future use, namely: | ||
* All [SmartREST 2.0](/smartrest/smartrest-two) related topics | ||
* `error` | ||
* `devicecontrol/notifications` | ||
|
||
Other than that you are free to use any topic name which is compatible with the [MQTT specification](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718106). | ||
|
||
{{< c8y-admon-info >}} | ||
Wildcard topics (`+`, `#`) and system topics starting with `$` are not supported. | ||
{{< /c8y-admon-info >}} | ||
|
||
#### Topic limit {#topic-limit} | ||
|
||
MQTT Service has the ability to limit the total number of topics that a single tenant can create. The current default is no limit. | ||
When the creation of a new topic, either by creating it via the client publishing a message or subscribing to a non-existent topic, would breach the topic limit | ||
the delivery of the packet is prevented. | ||
|
||
The different MQTT protocols provide the following feedback. | ||
|
||
MQTT 5 clients: | ||
|
||
* Have access to the reason code and reason string describing the failure when using QoS 1 with acknowledgements, | ||
reason code being `QUOTA_EXCEEDED: 0x97`. | ||
|
||
MQTT 3.1 and 3.1.1 clients: | ||
|
||
* Clients only have access to the reason code describing the failure when using QoS 1 with acknowledgements and only | ||
for the SUBSCRIBE packets, where the reason code is `0x80`. | ||
* For the PUBLISH packets, the client will be disconnected with no further information as per the MQTT specification. | ||
|
||
#### Error Topic {#error-topic} | ||
|
||
MQTT Service provides clients the ability to review errors through messages received by subscribing to the error topic, `$debug/$error`. | ||
When subscribing to the topic it will act as a per-client topic, meaning the client will only receive messages exclusively related to their client ID. For example, | ||
if a client was attempting to subscribe to a new topic, and the creation of the topic would exceed the topic limit, only that client would receive an error. | ||
|
||
According to the MQTT 3.1.1 specification, if either the server or the client encounters a protocol violation, it must close the network connection on | ||
which it received the control packet which caused the violation. | ||
|
||
In such instances MQTT clients must reconnect to be able to receive error messages from the error topic via the subscription. Error messages received after this reconnection | ||
are from the previous session. This can lead to confusion when attempting corrective actions. Therefore, we highly recommend you to build a microservice which uses | ||
the MQTT Service SDK to consume error messages, or use MQTT 5 for clients and make use of the reason codes feature. | ||
|
||
#### Topic cleanup {#topic-cleanup} | ||
|
||
The MQTT service will automatically remove topics which are no longer active. Topics are recognized as inactive when there are no subscriptions and | ||
the internal publisher to the topic is closed. The publisher is responsible for publishing the modified MQTT service messages to the correct topic. | ||
The publishers live within a cache, where the publisher expires after one hour. Due to this it can take up to an hour after removing all subscriptions from a topic | ||
for it to be automatically deleted. | ||
|
||
### Payload {#payload} | ||
|
||
The original MQTT messages are re-packed into MQTT Service message format which includes the original payload and additional metadata fields. | ||
Assuming Java types, the packed message structure looks as follows: | ||
|
||
`MqttServiceMessage` | ||
| Field name | Type | Description | | ||
|:-----------|:--------------------|:-------------------------------| | ||
| payload | byte[] | MQTT payload | | ||
| metadata | MqttServiceMetadata | Metadata from the MQTT message | | ||
|
||
`MqttServiceMetadata` | ||
| Field name | Type | Description | | ||
|:-----------------------|:--------|:------------------------------------------------------------------------| | ||
| clientId | String | Unique MQTT client identifier, usually used as an external identifier | | ||
| messageId | int | Unique MQTT message ID per client, available only with QoS 1 and 2 | | ||
| dupFlag | boolean | Indicates this message is a resend by the MQTT client | | ||
| userProperties | Map | Reserved for future use of MQTT 5.0 features | | ||
| payloadFormatIndicator | enum | Reserved for future use of MQTT 5.0 features | | ||
| contentType | String | Reserved for future use of MQTT 5.0 features | | ||
| correlationData | byte[] | Reserved for future use of MQTT 5.0 features | | ||
| responseTopic | String | Reserved for future use of MQTT 5.0 features | | ||
| topic | String | The name of the MQTT topic that the message was published by the client | | ||
|
||
The [Java Client](/device-integration/mqtt-service#java-client) contains classes representing the above model. | ||
|
||
#### Payload restrictions {#payload-restrictions} | ||
|
||
MQTT Service doesn't force you to use any specific payload format. | ||
All the incoming MQTT messages must meet the specification in terms of fixed and variable headers, but the payload for published messages is unrestricted. | ||
Just keep in mind that you will receive exactly the same set of bytes which was sent from the device in your custom microservice | ||
and you have to convert them to {{< product-c8y-iot >}} compatible format. | ||
|
||
{{< c8y-admon-info >}} | ||
For all MQTT connections to the platform, the maximum accepted payload size is 1048576 bytes (1 MiB), which includes | ||
both message header and body. The header size varies, but its minimum is 2 bytes. | ||
{{< /c8y-admon-info >}} | ||
|
||
### Features {#features} | ||
|
||
#### Authentication and authorization {#authentication-and-authorization} | ||
|
||
Authentication types supported by MQTT Service are: | ||
|
||
* Username and password: The MQTT username must include the tenant ID and username in the format `<tenantID>/<username>`. | ||
* Device certificates: Not yet supported. This will be added in a future release. | ||
|
||
#### ClientId {#client-id} | ||
|
||
The **MQTT ClientID** field identifies the connected client. **ClientID** may consist of up to 128 alphanumeric characters. | ||
Each client connecting to MQTT Service must have a unique client identifier, connecting a second client with the same identifier will result in the previous client's disconnection. | ||
|
||
#### Quality of Service (QoS) {#quality-of-service-qos} | ||
|
||
The {{< product-c8y-iot >}} implementation supports two levels of MQTT QoS: | ||
|
||
* QoS 0: At most once: | ||
- The client just sends the message once (fire and forget). | ||
- No response from the server. | ||
- No guarantee that subscribers will receive the message. | ||
* QoS 1: At least once: | ||
- The client awaits server acknowledgment for each published message. | ||
- The client should re-send the message if there was no acknowledgement from the server. | ||
- It is guaranteed that subscribers will receive a message that was acknowledged by the server. | ||
- Subscribers may receive more than one copy of a message. | ||
* QoS 2: Exactly once: | ||
- not supported | ||
|
||
For subscriptions, MQTT Service will deliver all messages in the QoS that the client defined when subscribing to the topic. | ||
|
||
#### Clean session {#clean-session} | ||
|
||
MQTT Service requires clean session to be set to "1" (true). We cannot guarantee that disabling clean session will work reliably, hence we recommend you to always enable clean session. | ||
|
||
#### Retained flag {#retained-flag} | ||
|
||
Retained flag is ignored. Publishing data with the retained flag on the topic is allowed but has no practical difference to sending it without the flag. | ||
|
||
#### Last will {#last-will} | ||
|
||
In MQTT, the "last will" is a message that is specified at connection time and that is executed when the client loses the connection. | ||
Last will is fully supported by MQTT Service and like with any other publish messages you can use any unreserved topic and any payload. | ||
|
||
### Return codes {#return-codes} | ||
|
||
MQTT Service follows the MQTT specification for server responses. For example, if invalid credentials are sent in the `CONNECT` message, | ||
the server response `CONNACK` message contains the `0x05` return code. | ||
The return code can be treated similarly to REST API HTTP codes, such as 401. | ||
|
||
### MQTT 5.0 features {#mqtt-50-features} | ||
|
||
Support for MQTT 5.0 features will be added in the near future. | ||
|
||
### MQTT TLS certificates {#mqtt-tls-certificates} | ||
|
||
MQTT Service uses the certificates which are assigned to the main environment domain. It always sends these certificates during TLS handshake to devices. | ||
Moreover, {{< enterprise-tenant >}}s are not able to customize those certificates via the SSL Management feature. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
title: MQTT service | ||
headless: true | ||
--- |
77 changes: 77 additions & 0 deletions
77
content/device-integration/mqtt-service-bundle/java-client.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
--- | ||
weight: 30 | ||
layout: redirect | ||
title: Java Client | ||
--- | ||
|
||
The MQTT Service Java Client library provides the classes necessary to interact with MQTT Service. | ||
The following operations are supported by the client: | ||
* Publishing messages to the MQTT Service via WebSocket protocol. | ||
* Subscribing to messages from the MQTT Service via WebSocket protocol | ||
|
||
#### Repositories and dependencies {#repositories-and-dependencies} | ||
|
||
Follow the [Microservice SDK](/microservice-sdk/java/#add-repositories-and-dependencies) documentation for guidance on how to configure Maven repositories. | ||
To include MQTT Service Java Client into your project, add the following dependency inside the `<dependencies>` node: | ||
```xml | ||
<dependency> | ||
<groupId>com.cumulocity.sdk.mqtt</groupId> | ||
<artifactId>mqtt-service-ws</artifactId> | ||
<version>${c8y.version}</version> | ||
</dependency> | ||
``` | ||
|
||
#### Example {#example} | ||
Example of publishing messages to the MQTT Service via WebSocket: | ||
```java | ||
// Message to be sent | ||
final String payload = "Hello World"; | ||
|
||
// Construct a new MqttServiceMessage and set the payload | ||
final MqttServiceMessage message = new MqttServiceMessage(); | ||
message.setPayload(payload.getBytes()); | ||
|
||
// Create an instance of MqttServiceApi by specifying the server URI to connect to along with TokenApi | ||
final MqttServiceApi mqttServiceApi = MqttServiceApi.webSocket() | ||
.url(webSocketBaseUrl) | ||
.tokenApi(tokenApi) | ||
.build(); | ||
|
||
// Build PublisherConfig with topic to which the message is to be sent | ||
final PublisherConfig config = PublisherConfig.publisherConfig().topic(topic).build(); | ||
|
||
// Build Publisher and publish MqttServiceMessage. Close the resource either by using a [try-with-resources block](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) as below or by calling publisher.close() explicitly | ||
try (final Publisher publisher = mqttServiceApi.buildPublisher(config)) { | ||
publisher.publish(message); | ||
} catch (Exception e) { | ||
log.error("Could not sent message to {}", topic, e); | ||
} | ||
mqttServiceApi.close(); | ||
``` | ||
|
||
Example of subscribing to messages from the MQTT Service via WebSocket: | ||
```java | ||
// Create an instance of MqttServiceApi by specifying the server URI to connect to along with TokenApi | ||
final MqttServiceApi mqttServiceApi = MqttServiceApi.webSocket() | ||
.url(webSocketBaseUrl) | ||
.tokenApi(tokenApi) | ||
.build(); | ||
|
||
// Build SubscriberConfig with topic and subscriber name | ||
final SubscriberConfig config = SubscriberConfig.subscriberConfig().topic(topic).subscriber(subscriberName).build(); | ||
|
||
// Build Subscriber | ||
final Subscriber subscriber = mqttServiceApi.buildSubscriber(config); | ||
|
||
// Subscribe by passing implementation of MessageListener to handle messages from the MQTT Service. | ||
subscriber.subscribe(new MessageListener() { | ||
@Override | ||
public void onMessage(MqttServiceMessage message) { | ||
log.info("Message Received: {}", new String(message.getPayload())); | ||
} | ||
}); | ||
|
||
// Close the resources after usage | ||
subscriber.close(); | ||
mqttServiceApi.close(); | ||
``` |
64 changes: 64 additions & 0 deletions
64
content/device-integration/mqtt-service-bundle/overview.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
--- | ||
weight: 10 | ||
layout: redirect | ||
title: Overview | ||
--- | ||
|
||
{{< c8y-admon-preview >}} | ||
This feature is in Private Preview, that is, it is not enabled by default and maybe subject to change in the future. | ||
Please reach out to the [product support](/additional-resources/contacting-support/) if you are interested in this feature. | ||
{{< /c8y-admon-preview >}} | ||
|
||
{{< c8y-admon-req >}} | ||
To work with the MQTT Service, the following requirements have to be met: | ||
* The {{< product-c8y-iot >}} Messaging Service must be available on your {{< product-c8y-iot >}} platform. | ||
* MQTT Service must be enabled for your tenant. | ||
{{< /c8y-admon-req >}} | ||
|
||
MQTT Service is the new MQTT endpoint implementation of {{< product-c8y-iot >}} which provides the following benefits: | ||
|
||
* Support for publishing and subscribing arbitrary payloads on any MQTT topic. The topics that are used by the existing {{< product-c8y-iot >}} MQTT implementation are not permitted for use with MQTT Service. | ||
* Support for subscribing to the data stream from MQTT Service and mapping it to {{< product-c8y-iot >}} compatible one or routing them to a different service. | ||
* Multi-tenancy support: A single endpoint serves multiple tenants. | ||
* Full horizontal scalability. | ||
|
||
This section does not describe the basics of MQTT communication. If you are unfamiliar with MQTT, we recommend | ||
you to consult one of the numerous introductions on the internet. Some references can be found on the [MQTT website](https://mqtt.org/mqtt-specification/). | ||
|
||
### Architecture {#architecture} | ||
|
||
MQTT Service works together with the Messaging Service to provide a framework for highly customizable and flexible MQTT message processing solutions. | ||
The diagram below illustrates how a message flows, starting from the device, through the Messaging Service, | ||
then to the microservice where it is converted to the final {{< product-c8y-iot >}} REST request. | ||
|
||
![MQTT Service send](/images/mqtt-service/mqtt-service-send.svg) | ||
|
||
All MQTT messages coming to MQTT Service are forwarded to the Messaging Service, where they are persisted, waiting to be consumed. | ||
A custom microservice that understands the topic and payload structure can, with the help of [Java Client](/device-integration/mqtt-service#java-client), | ||
consume the MQTT messages, translate them to the {{< product-c8y-iot >}} format, and then use the [Microservice SDK](/microservice-sdk/java) to push them into {{< product-c8y-iot >}}. | ||
|
||
Similarly, messages can be sent to devices, as shown in the diagram below. | ||
|
||
![MQTT Service push](/images/mqtt-service/mqtt-service-push.svg) | ||
|
||
Like with the message coming from the device the same solution can be also applied when trying to communicate with the device. | ||
Given the MQTT client ID and the topic, a microservice can push any MQTT message to a device via [Java Client](/device-integration/mqtt-service#java-client). | ||
|
||
### MQTT Service vs {{< product-c8y-iot >}} MQTT {#mqtt-service-vs-cumulocity-iot-mqtt} | ||
|
||
The table below presents a basic comparison between the standard {{< product-c8y-iot >}} MQTT functionality and that of MQTT Service. | ||
|
||
| | {{< product-c8y-iot >}} MQTT | MQTT Service | | ||
|:-----------------------------|:--------------------------------------------------------|:----------------------------------------------------------------------------------| | ||
| QoS | 0, 1, 2 | 0, 1 | | ||
| Clean session | Starting with clean session is recommended | Starting with clean session is recommended | | ||
| Retained flag | Not supported | Not supported | | ||
| Last will | Supported | Supported | | ||
| MQTT 5.0 features | Not supported | Support is planned | | ||
| Authentication | Basic and device certificate | Basic authentication is supported, device certificate support is planned | | ||
| Scalability | Horizontal | Horizontal | | ||
| Topic format | Determined by the SmartREST 2.0 protocol | Unrestricted, SmartREST topic names are reserved and cannot currently be used | | ||
| Payload | Determined by the SmartREST 2.0 protocol | Unrestricted, maximum message size is 1048576 bytes (1 MiB) including all headers | | ||
| Extensibility | Limited by SmartREST 2.0 custom templates | Custom mapping microservices can support arbitrary MQTT-based protocols | | ||
| Message processors/consumers | Build-in message processor for each SmartREST 2.0 topic | Custom mapping microservices can support multiple processors for a topic | | ||
| JSON via MQTT | Limited feature set | Custom mapping microservices can support arbitrary JSON payloads | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
weight: 26 | ||
title: MQTT Service | ||
layout: bundle | ||
section: | ||
- device_management | ||
--- |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be
sector
? Noticed the left-hand pane was a little broken, and I think this is the reason: