diff --git a/docs/content/apis/dmf_api.md b/docs/content/apis/dmf_api.md index 20d0c92040..1c024fe3f2 100644 --- a/docs/content/apis/dmf_api.md +++ b/docs/content/apis/dmf_api.md @@ -33,269 +33,516 @@ The following chapter describes the message body, header and properties. Note: the DMF protocol was intended to be compatible to other use cases by design. As a result, DMF uses the term **thing** and not **target** but they are actually synonyms in this case. -## Messages sent to hawkBit +## Messages sent to hawkBit (Client -> hawkBit) -All messages have to be sent to the exchange **dmf.exchange**. -### Message to register a thing +### THING_CREATED -| Message Header | Description | Type | Mandatory | -| -------------- | -------------------------------- | ----------------------------- | --------- | -| type | Type of the message | Fixed string "THING_CREATED " | true | -| thingId | The ID of the registered thing | String | true | -| tenant | The tenant this thing belongs to | String | true | +Message to register and update a provisioning target. -| Message Properties | Description | Type | Mandatory | -| ------------------ | --------------------- | ------ | --------- | -| reply_to | Exchange to reply to. | String | true | +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 -**Example Header** +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 -| Headers | MessageProperties | -| ------------------------------------------------------------- | -------------------------- | -| type=THING_CREATED
tenant=tenant123
thingId=abc | reply_to=dmfclient.replyTo | +Example headers -### Message to update target attributes +Header | MessageProperties +----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- +type=THING\_CREATED
tenant=tenant123
thingId=abc
sender=Lwm2m | content\_type=application/json
reply_to (optional) =sp.connector.replyTo -| Message Header | Description | Type | Mandatory | -| -------------- | -------------------------------- | -------------------------------- | --------- | -| type | Type of the message | Fixed string "EVENT" | true | -| topic | Topic to handle events different | Fixed string "UPDATE_ATTRIBUTES" | true | -| thingId | The ID of the registered thing | String | true | -| tenant | The tenant this thing belongs to | String | true | +### UPDATE_ATTRIBUTES -| Message Properties | Description | Type | Mandatory | -| ------------------ | ------------------------------- | ------ | --------- | -| content_type | The content type of the payload | String | true | +Message to update target attributes. This message can be send in response to a _REQUEST_ATTRIBUTES_UPDATE_ event, sent by hawkBit. -**Example Header and Payload** +| 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 -| Headers | MessageProperties | -| ------------------------------------------------------------------------------------ | ----------------------------- | -| type=EVENT
tenant=tenant123
thingId=abc
topic=UPDATE_ATTRIBUTES | content_type=application/json | -Payload Template +| Message Properties | Description | Type | Mandatory | +|-----------------------------|----------------------------------|--------|-----------| +| content_type | The content type of the payload | String | true | + +Example header and payload: + +| Header | MessageProperties | +|---------------------------------------|---------------------------------| +| type=EVENT
tenant=tenant123
thingId=abc
topic=UPDATE\_ATTRIBUTES | content\_type=application/json
+ +Payload Template: ```json { - "attributes": { - "exampleKey1": "exampleValue1", - "exampleKey2": "exampleValue2" - } + "attributes": { + "exampleKey1" : "exampleValue1", + "exampleKey2" : "exampleValue2" + }, + "mode": "String" } ``` -### Message to send an action status event to hawkBit +The "mode" property specifies the update mode that should be applied. This property is optional. Possible [mode](https://github.com/eclipse/hawkbit/tree/master/hawkbit-dmf/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DmfUpdateMode.java) 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. -The Java representation is ActionUpdateStatus: -| Header | Description | Type | Mandatory | -| ------ | -------------------------------- | ----------------------------------- | --------- | -| type | Type of the message | Fixed string "EVENT" | true | -| topic | Topic to handle events different | Fixed string "UPDATE_ACTION_STATUS" | true | -| tenant | The tenant this thing belongs to | String | true | +### UPDATE_ACTION_STATUS -| Message Properties | Description | Type | Mandatory | -| ------------------ | ------------------------------- | ------ | --------- | -| content_type | The content type of the payload | String | true | +Message to send an action status event to hawkBit. -Payload Template +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](https://github.com/eclipse/hawkbit/tree/master/hawkbit-dmf/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DmfActionUpdateStatus.java)): ```json { "actionId": long, "softwareModuleId": long, - "actionStatus": "String", - "message": ["String"] + "actionStatus":"String", + "message":["String"] } ``` -Possible actionStatus +Possible [actionStatus](https://github.com/eclipse/hawkbit/tree/master/hawkbit-dmf/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DmfActionStatus.java) values: -| Header | Description | -| --------------- | ------------------------------------------------- | -| DOWNLOAD | Device is downloading | -| RETRIEVED | Device management service has retrieved something | -| RUNNING | Update is running | -| FINISHED | Update process finished successful | -| ERROR | Error during update process | -| WARNING | Warning during update process | -| CANCELED | Cancel update process successful | -| CANCEL_REJECTED | Cancel update process has been rejected | +Value | Description +--------------- | --------------------------------------- +DOWNLOAD | Device is downloading +DOWNLOADED | Device completed download +RETRIEVED | Device has retrieved the artifact +RUNNING | Update is running +FINISHED | Update process finished successful +ERROR | Error during update process +WARNING | Warning during update process +CANCELED | Cancel update process successful +CANCEL_REJECTED | Cancel update process has been rejected -**Example Header and Payload** +Example header and payload: -| Headers | MessageProperties | -| -------------------------------------------------------------------- | ----------------------------- | -| type=EVENT
tenant=tenant123
topic=UPDATE_ACTION_STATUS | content_type=application/json | +Header | MessageProperties +----------------------------------------------------------------------- | ----------------------------- +type=EVENT
tenant=tenant123
topic=UPDATE\_ACTION\_STATUS | content_type=application/json ```json { - "actionId": 137, - "softwareModuleId": 17, - "actionStatus": "DOWNLOAD", - "message": ["The download has started"] + "actionId":137, + "softwareModuleId":17, + "actionStatus":"DOWNLOAD", + "message":["The download has started"] } ``` -### Message to cancel an update task +### PING + +hawkBit 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 + -| Header | Description | Type | Mandatory | -| ------- | -------------------------------- | ------------------------------ | --------- | -| type | Type of the message | Fixed string "Event" | true | -| thingId | The ID of the registered thing | String | true | -| topic | Topic to handle events different | Fixed string "CANCEL_DOWNLOAD" | true | -| tenant | The tenant this thing belongs to | String | true | +Message Properties | Description | Type | Mandatory +------------------ | ------------------------------- | ------ | ------------------------------------------------------------- +correlationId | CorrelationId that allows the client to map a PING request to PING_RESPONSE | String | true -| Message Properties | Description | Type | Mandatory | -| ------------------ | ------------------------------- | ------ | --------- | -| content_type | The content type of the payload | String | true | -Payload Template +## Messages sent by hawkBit (hawkBit -> Client) + +### CANCEL_DOWNLOAD + +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: ```json { - "actionId": long + "actionId": long } ``` -**Example Header and payload** +Example Headers and Payload: -| Headers | MessageProperties | -| ---------------------------------------------------------------------------------- | ----------------------------- | -| type=EVENT
tenant=tenant123
thingId=abc
topic=CANCEL_DOWNLOAD | content_type=application/json | +| Header | MessageProperties | +|---------------------------------------|---------------------------------| +| type=EVENT
tenant=tenant123
thingId=abc
topic=CANCEL\_DOWNLOAD | content_type=application/json ```json { - "actionId": 137 +"actionId":137 } ``` -After this message has been sent, an action status event with either actionStatus=CANCELED or actionStatus=CANCEL_REJECTED has to be returned. +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** +Example header and payload when cancellation is successful: -| Headers | MessageProperties | -| -------------------------------------------------------------------- | ----------------------------- | -| type=EVENT
tenant=tenant123
topic=UPDATE_ACTION_STATUS | content_type=application/json | +Header | MessageProperties +----------------------------------------------------------------------- | ----------------------------- +type=EVENT
tenant=tenant123
topic=UPDATE\_ACTION\_STATUS | content_type=application/json ```json { - "actionId": 137, - "softwareModuleId": 17, - "actionStatus": "CANCELED", - "message": ["The update was canceled."] + "actionId":137, + "softwareModuleId":17, + "actionStatus":"CANCELED", + "message":["The update was canceled."] } ``` -**Example Header and Payload when cancellation was rejected** +Example header and payload when cancellation is rejected: -| Headers | MessageProperties | -| -------------------------------------------------------------------- | ----------------------------- | -| type=EVENT
tenant=tenant123
topic=UPDATE_ACTION_STATUS | content_type=application/json | +Header | MessageProperties +----------------------------------------------------------------------- | ----------------------------- +type=EVENT
tenant=tenant123
topic=UPDATE\_ACTION\_STATUS | content_type=application/json ```json { - "actionId": 137, - "softwareModuleId": 17, - "actionStatus": "CANCEL_REJECTED", - "message": [ - "The cancellation was not possible since the target sent an unexpected response." - ] + "actionId":137, + "softwareModuleId":17, + "actionStatus":"CANCEL_REJECTED", + "message":["The cancellation was not possible since the target sent an unexpected response."] } ``` -## Messages sent by hawkBit -All messages from hawkBit will be sent to the specified exchange in the `reply_to` property. +### DOWNLOAD_AND_INSTALL or DOWNLOAD -### Message sent by hawkBit to initialize an update task +Message sent by hawkBit 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 thing | String | true | -| topic | Topic to handle events different | Fixed string "DOWNLOAD_AND_INSTALL" | true | -| tenant | The tenant this thing belongs to | String | true | +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 | +Message Properties | Description | Type | Mandatory +------------------ | ------------------------------- | ------ | ------------------------------------------------------------- +content_type | The content type of the payload | String | true -The Java representation is DownloadAndUpdateRequest: - -Payload Template +Payload Template (the Java representation is [DmfDownloadAndUpdateRequest](https://github.com/eclipse/hawkbit/tree/master/hawkbit-dmf/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DmfDownloadAndUpdateRequest.java)): ```json { - "actionId": long, - "targetSecurityToken": "String", - "softwareModules": [ +"actionId": long, +"targetSecurityToken": "String", +"softwareModules":[ { - "moduleId": long, - "moduleType": "String", - "moduleVersion": "String", - "artifacts": [ + "moduleId": long, + "moduleType":"String", + "moduleVersion":"String", + "artifacts":[ { - "filename": "String", - "urls": { - "HTTP": "String", - "HTTPS": "String" - }, - "hashes": { - "md5": "String", - "sha1": "String" - }, - "size": long - } - ], - "metadata": [ + "filename":"String", + "urls":{ + "HTTP":"String", + "HTTPS":"String" + }, + "hashes":{ + "md5":"String", + "sha1":"String" + }, + "size":long + }], + "metadata":[ { - "key": "String", - "value": "String" + "key":"String", + "value":"String" } - ] - } - ] + ] + }] } ``` -**Example Header and Payload** +Example header and payload: -| Headers | MessageProperties | -| --------------------------------------------------------------------------------------- | ----------------------------- | -| type=EVENT
tenant=tenant123
thingId=abc
topic=DOWNLOAD_AND_INSTALL | content_type=application/json | +Header | MessageProperties +------------------------------------------------------------------------------------------- | ----------------------------- +type=EVENT
tenant=tenant123
thingId=abc
topic=DOWNLOAD\_AND\_INSTALL | content_type=application/json ```json { - "actionId": 137, - "targetSecurityToken": "bH7XXAprK1ChnLfKSdtlsp7NOlPnZAYY", - "softwareModules": [ +"actionId":137, +"targetSecurityToken":"bH7XXAprK1ChnLfKSdtlsp7NOlPnZAYY", +"softwareModules":[ { - "moduleId": 7, - "moduleType": "firmware", - "moduleVersion": "7.7.7", - "artifacts": [ + "moduleId":7, + "moduleType":"firmware", + "moduleVersion":"7.7.7", + "artifacts":[ { - "filename": "artifact.zip", - "urls": { - "HTTP": "http://download-from-url.com", - "HTTPS": "https://download-from-url.com" - }, - "hashes": { - "md5": "md5hash", - "sha1": "sha1hash" - }, - "size": 512 - } - ], - "metadata": [ + "filename":"artifact.zip", + "urls":{ + "HTTP":"http://download-from-url.com", + "HTTPS":"https://download-from-url.com" + }, + "hashes":{ + "md5":"md5hash", + "sha1":"sha1hash" + }, + "size":512 + }], + "metadata":[ { - "key": "installationType", - "value": "5784K#" + "key":"installationType", + "value":"5784K#" } - ] - } - ] + ] + }] } ``` + + +### MULTI_ACTION + +If `multi.assignments.enabled` is enabled, this message is sent instead of DOWNLOAD_AND_INSTALL, DOWNLOAD, or CANCEL_DOWNLOAD + by hawkBit 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](https://github.com/eclipse/hawkbit/tree/master/hawkbit-dmf/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DmfMultiActionRequest.java)): + +```json +[{ +"topic": "String", +"action": { + "actionId": long, + "targetSecurityToken": "String", + "softwareModules":[ + { + "moduleId": long, + "moduleType":"String", + "moduleVersion":"String", + "artifacts":[ + { + "filename":"String", + "urls":{ + "HTTP":"String", + "HTTPS":"String" + }, + "hashes":{ + "md5":"String", + "sha1":"String" + }, + "size":long + }], + "metadata":[ + { + "key":"String", + "value":"String" + } + ] + }] + } +}, +{ +"topic": "String", +"action": { + "actionId": long, + "targetSecurityToken": "String", + "softwareModules":[ + { + "moduleId": long, + "moduleType":"String", + "moduleVersion":"String", + "artifacts":[ + { + "filename":"String", + "urls":{ + "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 + +```json +[{ +"topic": "DOWNLOAD_AND_INSTALL", +"action": { + "actionId":137, + "targetSecurityToken":"bH7XXAprK1ChnLfKSdtlsp7NOlPnZAYY", + "softwareModules":[ + { + "moduleId":7, + "moduleType":"firmware", + "moduleVersion":"7.7.7", + "artifacts":[ + { + "filename":"artifact.zip", + "urls":{ + "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", +"action": { + "actionId":138, + "targetSecurityToken":"bH7XXAprK1ChnLfKSdtlsp7NOlPnZAYY", + "softwareModules":[ + { + "moduleId":4, + "moduleType":"firmware", + "moduleVersion":"7.7.9", + "artifacts":[ + { + "filename":"artifact.zip", + "urls":{ + "HTTP":"http://download-from-url.com", + "HTTPS":"https://download-from-url.com" + }, + "hashes":{ + "md5":"md5hash", + "sha1":"sha1hash" + }, + "size":512 + }], + "metadata":[ + { + "key":"installationType", + "value":"5784K#" + } + ] + }] + } +}] +``` + + +### THING_DELETED + +Message sent by hawkBit 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 | | + + +### REQUEST_ATTRIBUTES_UPDATE + +Message sent by Eclipse hawkBit 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 | | + + +### PING_RESPONSE + +_hawkBit_ 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 | + +```text +1505215891247 +``` diff --git a/docs/content/concepts/rollout-management.md b/docs/content/concepts/rollout-management.md index 6a84ec30e3..21d6b416a3 100644 --- a/docs/content/concepts/rollout-management.md +++ b/docs/content/concepts/rollout-management.md @@ -47,3 +47,26 @@ The cascading execution of the deployment groups is based on two thresholds that ### State Machine on Rollout Deployment Group ![](../../images/rolloutgroupstatediagram.png) + +## Multi-Assignments (beta) + +One of the main paradigms of Eclipse hawkBit is, that a Distribution Set represents the currently installed software of a device. Hence, a device can have only one Distribution Set assigned/installed at a time. With _Multi-Assignments_ enabled, this paradigm shifts. Multi-Assignments allows to assign multiple Distribution Sets to a device simultaneously, without cancelling each other. As a consequence, an operator can trigger multiple campaigns addressing the same devices in parallel. + +### Consequences + +While this feature provides more flexibility to the user and enables new use-cases, there are also some consequences one should be aware of: + +**Critical** + +* This feature is in beta and may change unannounced. +* For now, this feature is **opt-in only**. Once activated, it cannot be deactivated. +* Currently, there is no mechanism to hint devices to process the actions in a certain order. + +**Minor** + +* While on DMF-API a MULTI_ACTION request is sent, DDI-API only exposes the oldest open action. +* All information regarding the currently assigned or installed Distribution Set does only respect the last assignment, as well as the last successfully installed Distribution set. This also affects: + * Pinning a target or Distribution Set in Deployment View. + * Statistics about installed or assigned Distribution Sets. +* Auto close running actions, when a new Distribution Set is assigned (`repository.actions.autoclose.enabled`) is deactivated. +* Marking a Distribution Set to be a *Required Migration Step* is deactivated. \ No newline at end of file