The purpose of the DMF API is indirect device integration through a device management service into Rollouts. It is message based and optimized for cloud service-to-service interaction. The message transport is AMQP 0-9-1 compatible with message bodies in JSON. The API itself is compatible with the Eclipse hawkBit DMF API.
The DMF API is available in Free plan for evaluation purposes and in the Standard plan for productive use. Note that the API has to be activated (either by Management API or Management UI).
Please be aware of the existence of a Quota. We also recommend to check out the target and action state machines.
Bosch IoT Rollouts DMF API is fully compatible to Eclipse hawkBit’s DMF API in version 1 (v1).
The hawkBit project provides Java representations that allow to decode the message body at runtime into a Java object. The Java models can also be used to encode Java objects into JSON bodies to send a message to Rollouts.
The model is available on maven central, e.g. in maven:
<dependency> <groupId>org.eclipse.hawkbit</groupId> <artifactId>hawkbit-dmf-api</artifactId> <version>0.2.0</version> </dependency>
There are three basic concepts of AMQP:
Queues are just a place for receiving messages. Bindings determine how messages get into them. Queues can also be bound to multiple exchanges.
Exchanges are for publishing messages. The user decides who can publish on the exchange and who can create bindings on that exchange for delivery to a specific queue.
For communication Rollouts will create all necessary queues, exchanges and the bindings for the user. So it is very easy to communicate with Rollouts out of the box. The exchange name to sending a message to Rollouts is dmf.exchange.
The queue name to receive messages from Rollouts is sp_direct_queue.
Rollouts sends messages to the sp.direct.exchange which is bound to the sp_direct_queue.
The DMF message flow is provisioning target centric, i.e. there are no bulk messages for multiple targets/devices.
In general, the DMF API defines five messages:
Initial creation of a provisioning target if it does not exist in the repository yet (plug-and-play). If the device does exist it will result only in an update of the last poll time field of the target. In addition, Rollouts will also (re-)transmit open update actions back to the client. We generally recommend to send these polls on a regular basis, either whenever the device connects to the device management service or if it has a standing connection in a regular interval. That has the benefit of greater robustness as an update message might have gotten lost and leverages Rollouts capability to signal to the user that a device is overdue if the poll is coming in the defined time frame (see System Configuration for how to configure the expected poll schedule). Specification
Deletion of a provisioning target. If this message is sent, a hard deletion is triggered on Rollouts side, that also removes all associated metadata. The deletion can’t be undone. A THING_DELETED message is sent back to the client, that confirms the deletion of the target. Specification
Update command for a target. As mentioned above this message will be send when the update is started in Rollouts and resend after every THING_CREATED. Specification
Download only command for a target. As mentioned above this message will be send when the download is started in Rollouts and resend after every THING_CREATED. This message will be send instead of DOWNLOAD_AND_INSTALL if the Download Only deployment type is selected or if a maintenance window is configured but device is not in the next available window yet. Specification
Rollouts tries to inform the device about a canceled update. In many cases that might be too late and as a matter of fact devices can reject the cancellation and continue with the update (see below). Specification
When multi.assignments.enabled is enabled, this message exposes all open actions of the device and is sent instead of DOWNLOAD, DOWNLOAD_AND_INSTALL, and CANCEL_DOWNLOAD. Specification
Rollouts informs the device about a deletion of its representation on the Rollout Server. Consider that after a target is removed Rollouts will ignore corresponding event messages. Specification
The following diagram illustrates a typical DMF message flow:
In general, the AMQP based message transfer as used in DMF does not guarantee end-to-end delivery. However, we encourage DMF users to:
Note: The DMF protocol uses the term “thing” for a device or in Rollouts speech “provisioning target”. The terms can be considered as synonyms.
Messages sent to Rollouts (Client -> Rollouts)
Messages sent by Rollouts (Rollouts -> Client)
All messages have to be sent to the exchange dmf.exchange.
Message to register and update a provisioning target.
Header | Description | Type | Mandatory |
---|---|---|---|
type | Type of the message | Fixed string “THING_CREATED” | true |
thingId | The ID of the registered provisioning target | String | true |
sender | Name of the message sender | String | false |
tenant | The tenant this provisioning target belongs to | String | false |
Message Properties | Description | Type | Mandatory |
---|---|---|---|
content_type | The content type of the payload | String | true |
reply_to | Exchange to reply to. The default is sp.direct.exchange which is bound to the sp_direct_queue | String | false |
Example headers and payload:
Header | MessageProperties |
---|---|
type=THING_CREATED tenant=tenant123 thingId=abc sender=Lwm2m |
content_type=application/json reply_to (optional) =sp.connector.replyTo |
Payload Template (optional):
{ "name": "String" }
The “name” property specifies the name of the thing, which by default is the thing ID. This property is optional.
Message to request the deletion of a provisioning target.
Header | Description | Type | Mandatory |
---|---|---|---|
type | Type of the message | Fixed string “THING_REMOVED” | true |
thingId | The ID of the registered provisioning target | String | true |
tenant | The tenant this provisioning target belongs to | String | false |
Message Properties | Description | Type | Mandatory |
---|---|---|---|
content_type | The content type of the payload | String | true |
Example headers
Header | MessageProperties |
---|---|
type=THING_REMOVED tenant=tenant123 thingId=abc |
content_type=application/json |
Message to update target attributes. This message can be send in response to a REQUEST_ATTRIBUTES_UPDATE event, sent by Rollouts.
Header | Description | Type | Mandatory |
---|---|---|---|
type | Type of the message | Fixed string “EVENT” | true |
topic | Topic name identifying the event | Fixed string “UPDATE_ATTRIBUTES” | true |
thingId | The ID of the registered thing | String | true |
tenant | The tenant this thing belongs to | String | false |
Message Properties | Description | Type | Mandatory |
---|---|---|---|
content_type | The content type of the payload | String | true |
Example headers and payload:
Header | MessageProperties |
---|---|
type=EVENT tenant=tenant123 thingId=abc topic=UPDATE_ATTRIBUTES |
content_type=application/json |
Payload Template:
{ "attributes": { "exampleKey1" : "exampleValue1", "exampleKey2" : "exampleValue2" }, "mode": "String" }
The “mode” property specifies the update mode that should be applied. This property is optional. Possible mode values:
Value | Description |
---|---|
MERGE | The target attributes specified in the payload are merged into the existing attributes. This is the default mode that is applied if no “mode” property is specified in the payload. |
REPLACE | The existing attributes are replaced with the target attributes specified in the payload. |
REMOVE | The target attributes specified in the payload are removed from the existing attributes. |
Message to send an action status event to Rollouts.
Header | Description | Type | Mandatory |
---|---|---|---|
type | Type of the message | Fixed string “EVENT” | true |
topic | Topic name identifying the event | Fixed string “UPDATE_ACTION_STATUS” | true |
tenant | The tenant this thing belongs to | String | false |
Message Properties | Description | Type | Mandatory |
---|---|---|---|
content_type | The content type of the payload | String | true |
Payload Template (the Java representation is ActionUpdateStatus):
{ "actionId": long, "softwareModuleId": long, "actionStatus":"String", "message":["String"] }
Possible actionStatus values:
Value | Description |
---|---|
DOWNLOAD | Device is downloading |
DOWNLOADED | Device completed download |
RETRIEVED | Device has retrieved the artifact |
RUNNING | Update is running |
FINISHED | Update process finished successfully |
ERROR | Error during update process |
WARNING | Warning during update process |
CANCELED | Cancel update process successfully |
CANCEL_REJECTED | Cancel update process has been rejected |
Example header and payload:
Header | MessageProperties |
---|---|
type=EVENT tenant=tenant123 topic=UPDATE_ACTION_STATUS |
content_type=application/json |
{ "actionId":137, "softwareModuleId":17, "actionStatus":"DOWNLOAD", "message":["The download has started"] }
Rollouts allows DMF clients to check the availability of the DMF service. For this scenario DMF specifies a PING message that can be sent by the client:
Header | Description | Type | Mandatory |
---|---|---|---|
type | Type of the message | Fixed string “PING” | true |
tenant | The tenant the PING belongs to | String | false |
Message Properties | Description | Type | Mandatory |
---|---|---|---|
correlationId | CorrelationId that allows the client to map a PING request to PING_RESPONSE | String | true |
All messages from Rollouts are sent to the sp_direct_queue or to the exchange specified by the reply_to property.
Message to cancel an update task.
Header | Description | Type | Mandatory |
---|---|---|---|
type | Type of the message | Fixed string “Event” | true |
thingId | The ID of the registered provisioning target | String | true |
topic | Topic name identifying the event | Fixed string “CANCEL_DOWNLOAD” | true |
tenant | The tenant this provisioning target belongs to | String | false |
Message Properties | Description | Type | Mandatory |
---|---|---|---|
content_type | The content type of the payload | String | true |
Payload template:
{ "actionId": long }
Example Headers and Payload:
Header | MessageProperties |
---|---|
type=EVENT tenant=tenant123 thingId=abc topic=CANCEL_DOWNLOAD |
content_type=application/json |
{ "actionId":137 }
After sending this message, an action status event with either actionStatus=CANCELED or actionStatus=CANCEL_REJECTED has to be returned.
Example header and payload when cancellation is successful:
Header | MessageProperties |
---|---|
type=EVENT tenant=tenant123 topic=UPDATE_ACTION_STATUS |
content_type=application/json |
{ "actionId":137, "softwareModuleId":17, "actionStatus":"CANCELED", "message":["The update was canceled."] }
Example header and payload when cancellation is rejected:
Header | MessageProperties |
---|---|
type=EVENT tenant=tenant123 topic=UPDATE_ACTION_STATUS |
content_type=application/json |
{ "actionId":137, "softwareModuleId":17, "actionStatus":"CANCEL_REJECTED", "message":["The cancellation was not possible since the target sent an unexpected response."] }
Message sent by Rollouts to initialize an update or download task. Note: in case of a maintenance window configured but not yet active the message will have the topic DOWNLOAD instead of DOWNLOAD_AND_INSTALL.
Header | Description | Type | Mandatory |
---|---|---|---|
type | Type of the message | Fixed string “EVENT” | true |
thingId | The ID of the registered provisioning target | String | true |
topic | Topic name identifying the event | Fixed string “DOWNLOAD_AND_INSTALL” or “DOWNLOAD” | true |
tenant | The tenant this provisioning target belongs to | String | false |
Message Properties | Description | Type | Mandatory |
---|---|---|---|
content_type | The content type of the payload | String | true |
Payload Template (the Java representation is DmfDownloadAndUpdateRequest):
Note: targetSecurityToken will not be included if anonymous download is enabled.
{ "actionId": long, "targetSecurityToken": "String", "softwareModules":[ { "moduleId": long, "moduleType":"String", "moduleVersion":"String", "artifacts":[ { "filename":"String", "urls":{ "COAP":"String", "HTTP":"String", "HTTPS":"String" }, "hashes":{ "md5":"String", "sha1":"String" }, "size":long }], "metadata":[ { "key":"String", "value":"String" } ] }] }
Example header and payload:
Header | MessageProperties |
---|---|
type=EVENT tenant=tenant123 thingId=abc topic=DOWNLOAD_AND_INSTALL |
content_type=application/json |
{ "actionId":137, "targetSecurityToken":"bH7XXAprK1ChnLfKSdtlsp7NOlPnZAYY", "softwareModules":[ { "moduleId":7, "moduleType":"firmware", "moduleVersion":"7.7.7", "artifacts":[ { "filename":"artifact.zip", "urls":{ "COAP":"coap://download-from-url.com", "HTTP":"http://download-from-url.com", "HTTPS":"https://download-from-url.com" }, "hashes":{ "md5":"md5hash", "sha1":"sha1hash" }, "size":512 }], "metadata":[ { "key":"installationType", "value":"5784K#" } ] }] }
If multi.assignments.enabled is enabled, this message is sent instead of DOWNLOAD_AND_INSTALL, DOWNLOAD, or CANCEL_DOWNLOAD by Rollouts to initialize update, download, or cancel task(s).
Header | Description | Type | Mandatory |
---|---|---|---|
type | Type of the message | Fixed string “EVENT” | true |
thingId | The ID of the registered provisioning target | String | true |
topic | Topic name identifying the event | Fixed string “MULTI_ACTION” | true |
tenant | The tenant this provisioning target belongs to | String | false |
Message Properties | Description | Type | Mandatory |
---|---|---|---|
content_type | The content type of the payload | String | true |
Payload Template (the Java representation is DmfMultiActionRequest):
Note: targetSecurityToken will not be included if anonymous download is enabled.
[{ "topic": "String", "weight": long, "action": { "actionId": long, "targetSecurityToken": "String", "softwareModules":[ { "moduleId": long, "moduleType":"String", "moduleVersion":"String", "artifacts":[ { "filename":"String", "urls":{ "COAP":"String", "HTTP":"String", "HTTPS":"String" }, "hashes":{ "md5":"String", "sha1":"String" }, "size":long }], "metadata":[ { "key":"String", "value":"String" } ] }] } }, { "topic": "String", "weight": long, "action": { "actionId": long, "targetSecurityToken": "String", "softwareModules":[ { "moduleId": long, "moduleType":"String", "moduleVersion":"String", "artifacts":[ { "filename":"String", "urls":{ "COAP":"String", "HTTP":"String", "HTTPS":"String" }, "hashes":{ "md5":"String", "sha1":"String" }, "size":long }], "metadata":[ { "key":"String", "value":"String" } ] }] } }]
Example header and payload:
Header | MessageProperties |
---|---|
type=EVENT tenant=tenant123 thingId=abc topic=MULTI_ACTION |
content_type=application/json |
[{ "topic": "DOWNLOAD_AND_INSTALL", "weight": 500, "action": { "actionId":137, "targetSecurityToken":"bH7XXAprK1ChnLfKSdtlsp7NOlPnZAYY", "softwareModules":[ { "moduleId":7, "moduleType":"firmware", "moduleVersion":"7.7.7", "artifacts":[ { "filename":"artifact.zip", "urls":{ "COAP":"coap://download-from-url.com", "HTTP":"http://download-from-url.com", "HTTPS":"https://download-from-url.com" }, "hashes":{ "md5":"md5hash", "sha1":"sha1hash" }, "size":512 }], "metadata":[ { "key":"installationType", "value":"5784K#" } ] }] } }, { "topic": "DOWNLOAD", "weight": 300, "action": { "actionId":138, "targetSecurityToken":"bH7XXAprK1ChnLfKSdtlsp7NOlPnZAYY", "softwareModules":[ { "moduleId":4, "moduleType":"firmware", "moduleVersion":"7.7.9", "artifacts":[ { "filename":"artifact.zip", "urls":{ "COAP":"coap://download-from-url.com", "HTTP":"http://download-from-url.com", "HTTPS":"https://download-from-url.com" }, "hashes":{ "md5":"md5hash", "sha1":"sha1hash" }, "size":512 }], "metadata":[ { "key":"installationType", "value":"5784K#" } ] }] } }]
Message sent by Rollouts when a target has been deleted.
Header | Description | Type | Mandatory |
---|---|---|---|
type | Type of the message | Fixed string “THING_DELETED” | true |
thingId | The ID of the registered provisioning target | String | true |
tenant | The tenant this provisioning target belongs to | String | true |
Example header:
Header | MessageProperties |
---|---|
type=THING_DELETED tenant=tenant123 thingId=abc |
Message sent by Rollouts when a re-transmission of target attributes is requested.
Header | Description | Type | Mandatory |
---|---|---|---|
type | Type of the message | Fixed string “EVENT” | true |
thingId | The ID of the registered provisioning target | String | true |
topic | Topic name identifying the event | Fixed string “REQUEST_ATTRIBUTES_UPDATE” | true |
tenant | The tenant this provisioning target belongs to | String | true |
Example headers:
Header | MessageProperties |
---|---|
type=EVENT tenant=tenant123 thingId=abc topic=REQUEST_ATTRIBUTES_UPDATE |
Rollouts will respond to the PING message with a PING_RESPONSE type message that has the same correlationId as the original PING message:
Header | Description | Type | Mandatory |
---|---|---|---|
type | Type of the message | Fixed string “PING_RESPONSE” | true |
tenant | The tenant the PING belongs to | String | false |
Message Properties | Description | Type | Mandatory |
---|---|---|---|
correlationId | CorrelationId of the original PING request | String | true |
content_type | The content type of the payload | String | true |
The PING_RESPONSE also contains a timestamp (i.e. the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC) as plain text. It is not guaranteed that this timestamp is completely accurate.
Header | MessageProperties |
---|---|
type=PING_RESPONSE tenant=tenant123 |
content_type=text/plain |
1505215891247
Disclaimer: It is up to the (potentially clustered) client to relate the PING message to the corresponding PING_RESPONSE (which might be taken by another cluster node from the queue).