Fix DMF docs and unnecessary content_type enforcements. (#792)

* Fix DMF docs and unnecessary content_typ enforcements.

* One more error.

* Typo
This commit is contained in:
Kai Zimmermann
2019-02-01 12:09:11 +01:00
committed by GitHub
parent f9a7194fd5
commit 6095133019
3 changed files with 165 additions and 179 deletions

View File

@@ -6,6 +6,7 @@ weight: 83
The DMF API provides Java classes which allows that the message body can be deserialized at runtime into a Java object. Also Java classes can be used to serialize Java objects into JSON bodies to send a message to hawkBit. The DMF API provides Java classes which allows that the message body can be deserialized at runtime into a Java object. Also Java classes can be used to serialize Java objects into JSON bodies to send a message to hawkBit.
Currently, bodies of messages are based on JSON. Currently, bodies of messages are based on JSON.
<!--more--> <!--more-->
## Basics ## Basics
@@ -26,66 +27,61 @@ The user decides who can produce on an exchange and who can create bindings on t
hawkBit will create all necessary queues, exchanges and bindings for the user, making it easy to get started. hawkBit will create all necessary queues, exchanges and bindings for the user, making it easy to get started.
The exchange name for outgoing messages is **dmf.exchange**. The exchange name for outgoing messages is **dmf.exchange**.
The user has to set a ``reply_to`` header (see chapter below), to change the default sender exchange. The user has to set a `reply_to` header (see chapter below), to change the default sender exchange.
The following chapter describes the message body, header and properties. The following chapter describes the message body, header and properties.
Note: the DMF protocol was intended to be open for other non update use cases by design (e.g. [Eclipse Hono](https://github.com/eclipse/hono). As a result, DMF uses the term **thing** and not **target** but they are actually synonyms in this case. 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
All messages have to be sent to the exchange **dmf.exchange**. All messages have to be sent to the exchange **dmf.exchange**.
### Message to register a thing ### Message to register a thing
| Message Header | Description | Type | Mandatory | Message Header | Description | Type | Mandatory |
|-----------------------------|----------------------------------|-------------------------------------|---------------- | -------------- | -------------------------------- | ----------------------------- | --------- |
| type | Type of the message | Fixed string "THING_CREATED " | true | type | Type of the message | Fixed string "THING_CREATED " | true |
| thingId | The ID of the registered thing | String | true | thingId | The ID of the registered thing | String | true |
| sender | Name of the message sender | String | false | tenant | The tenant this thing belongs to | String | true |
| tenant | The tenant this thing belongs to | String | false
| Message Properties | Description | Type | Mandatory |
| Message Properties | Description | Type | Mandatory | ------------------ | --------------------- | ------ | --------- |
|-----------------------------|----------------------------------|-------------------------------------|---------------- | reply_to | Exchange to reply to. | String | true |
| content_type | The content type of the payload | String | true
| reply_to | Exchange to reply to. | String | false
**Example Header** **Example Header**
| Headers | MessageProperties | Headers | MessageProperties |
|---------------------------------------|--------------------------------- | ------------------------------------------------------------- | -------------------------- |
| type=THING\_CREATED <br /> tenant=tenant123 <br /> thingId=abc <br /> sender=Lwm2m | content\_type=application/json <br /> reply_to (optional) =sp.connector.replyTo | type=THING_CREATED <br /> tenant=tenant123 <br /> thingId=abc | reply_to=dmfclient.replyTo |
### Message to update target attributes ### Message to update target attributes
| Message Header | Description | Type | Mandatory | Message Header | Description | Type | Mandatory |
|-----------------------------|----------------------------------|-------------------------------------|---------------- | -------------- | -------------------------------- | -------------------------------- | --------- |
| type | Type of the message | Fixed string "EVENT" | true | type | Type of the message | Fixed string "EVENT" | true |
| topic | Topic to handle events different | Fixed string "UPDATE_ATTRIBUTES" | true | topic | Topic to handle events different | Fixed string "UPDATE_ATTRIBUTES" | true |
| thingId | The ID of the registered thing | String | true | thingId | The ID of the registered thing | String | true |
| tenant | The tenant this thing belongs to | String | false | tenant | The tenant this thing belongs to | String | true |
| 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 |
**Example Header and Payload** **Example Header and Payload**
| Headers | MessageProperties | Headers | MessageProperties |
|---------------------------------------|--------------------------------- | ------------------------------------------------------------------------------------ | ----------------------------- |
| type=EVENT <br /> tenant=tenant123 <br /> thingId=abc <br /> topic=UPDATE\_ATTRIBUTES | content\_type=application/json <br /> | type=EVENT <br /> tenant=tenant123 <br /> thingId=abc <br /> topic=UPDATE_ATTRIBUTES | content_type=application/json |
Payload Template Payload Template
```json ```json
{ {
"attributes": { "attributes": {
"exampleKey1" : "exampleValue1", "exampleKey1": "exampleValue1",
"exampleKey2" : "exampleValue2" "exampleKey2": "exampleValue2"
} }
} }
``` ```
@@ -93,86 +89,85 @@ Payload Template
The Java representation is ActionUpdateStatus: The Java representation is ActionUpdateStatus:
| Header | Description | Type | Mandatory | Header | Description | Type | Mandatory |
|-----------------------------|----------------------------------|-------------------------------------|-------------- | ------ | -------------------------------- | ----------------------------------- | --------- |
| type | Type of the message | Fixed string "EVENT" | true | type | Type of the message | Fixed string "EVENT" | true |
| topic | Topic to handle events different | Fixed string "UPDATE_ACTION_STATUS" | true | topic | Topic to handle events different | Fixed string "UPDATE_ACTION_STATUS" | true |
| tenant | The tenant this thing belongs to | String | false | tenant | The tenant this thing belongs to | String | true |
| Message Properties | Description | Type | Mandatory | Message Properties | Description | Type | Mandatory |
|-----------------------------|----------------------------------|-------------------------------------|---------------- | ------------------ | ------------------------------- | ------ | --------- |
| content_type | The content type of the payload | String | true | content_type | The content type of the payload | String | true |
Payload Template Payload Template
```json ```json
{ {
"actionId": long, "actionId": long,
"softwareModuleId": long, "softwareModuleId": long,
"actionStatus":"String", "actionStatus": "String",
"message":["String"] "message": ["String"]
} }
``` ```
Possible actionStatus Possible actionStatus
| Header | Description | Header | Description |
|-----------------|------------------------------------ | --------------- | ------------------------------------------------- |
| DOWNLOAD | Device is downloading | DOWNLOAD | Device is downloading |
| RETRIEVED | Device management service has retrieved something | RETRIEVED | Device management service has retrieved something |
| RUNNING | Update is running | RUNNING | Update is running |
| FINISHED | Update process finished successful | FINISHED | Update process finished successful |
| ERROR | Error during update process | ERROR | Error during update process |
| WARNING | Warning during update process | WARNING | Warning during update process |
| CANCELED | Cancel update process successful | CANCELED | Cancel update process successful |
| CANCEL_REJECTED | Cancel update process has been rejected | CANCEL_REJECTED | Cancel update process has been rejected |
**Example Header and Payload** **Example Header and Payload**
| Headers | MessageProperties | Headers | MessageProperties |
|---------------------------------------|--------------------------------- | -------------------------------------------------------------------- | ----------------------------- |
| type=EVENT <br /> tenant=tenant123 <br /> topic=UPDATE\_ACTION\_STATUS | content_type=application/json | type=EVENT <br /> tenant=tenant123 <br /> topic=UPDATE_ACTION_STATUS | content_type=application/json |
```json ```json
{ {
"actionId":137, "actionId": 137,
"softwareModuleId":17, "softwareModuleId": 17,
"actionStatus":"DOWNLOAD", "actionStatus": "DOWNLOAD",
"message":["The download has started"] "message": ["The download has started"]
} }
``` ```
### Message to cancel an update task ### Message to cancel an update task
| Header | Description | Type | Mandatory | Header | Description | Type | Mandatory |
|-----------------------------|----------------------------------|-------------------------------------|---------------- | ------- | -------------------------------- | ------------------------------ | --------- |
| type | Type of the message | Fixed string "Event" | true | type | Type of the message | Fixed string "Event" | true |
| thingId | The ID of the registered thing | String | true | thingId | The ID of the registered thing | String | true |
| topic | Topic to handle events different | Fixed string "CANCEL_DOWNLOAD" | true | topic | Topic to handle events different | Fixed string "CANCEL_DOWNLOAD" | true |
| tenant | The tenant this thing belongs to | String | false | tenant | The tenant this thing belongs to | String | true |
| Message Properties | Description | Type | Mandatory | Message Properties | Description | Type | Mandatory |
|-----------------------------|----------------------------------|-------------------------------------|---------------- | ------------------ | ------------------------------- | ------ | --------- |
| content_type | The content type of the payload | String | true | content_type | The content type of the payload | String | true |
Payload Template Payload Template
```json ```json
{ {
"actionId": long "actionId": long
} }
``` ```
**Example Header and payload** **Example Header and payload**
| Headers | MessageProperties | Headers | MessageProperties |
|---------------------------------------|--------------------------------- | ---------------------------------------------------------------------------------- | ----------------------------- |
| type=EVENT <br /> tenant=tenant123 <br /> thingId=abc <br /> topic=CANCEL\_DOWNLOAD | content_type=application/json | type=EVENT <br /> tenant=tenant123 <br /> thingId=abc <br /> topic=CANCEL_DOWNLOAD | content_type=application/json |
```json ```json
{ {
"actionId":137 "actionId": 137
} }
``` ```
@@ -180,122 +175,127 @@ After this message has been sent, an action status event with either actionStatu
**Example Header and Payload when cancellation is successful** **Example Header and Payload when cancellation is successful**
| Headers | MessageProperties | Headers | MessageProperties |
|---------------------------------------|--------------------------------- | -------------------------------------------------------------------- | ----------------------------- |
| type=EVENT <br /> tenant=tenant123 <br /> topic=UPDATE\_ACTION\_STATUS | content_type=application/json | type=EVENT <br /> tenant=tenant123 <br /> topic=UPDATE_ACTION_STATUS | content_type=application/json |
```json ```json
{ {
"actionId":137, "actionId": 137,
"softwareModuleId":17, "softwareModuleId": 17,
"actionStatus":"CANCELED", "actionStatus": "CANCELED",
"message":["The update was canceled."] "message": ["The update was canceled."]
} }
``` ```
**Example Header and Payload when cancellation was rejected** **Example Header and Payload when cancellation was rejected**
| Headers | MessageProperties | Headers | MessageProperties |
|---------------------------------------|--------------------------------- | -------------------------------------------------------------------- | ----------------------------- |
| type=EVENT <br /> tenant=tenant123 <br /> topic=UPDATE\_ACTION\_STATUS | content_type=application/json | type=EVENT <br /> tenant=tenant123 <br /> topic=UPDATE_ACTION_STATUS | content_type=application/json |
```json ```json
{ {
"actionId":137, "actionId": 137,
"softwareModuleId":17, "softwareModuleId": 17,
"actionStatus":"CANCEL_REJECTED", "actionStatus": "CANCEL_REJECTED",
"message":["The cancellation was not possible since the target sent an unexpected response."] "message": [
"The cancellation was not possible since the target sent an unexpected response."
]
} }
``` ```
## Messages sent by hawkBit ## Messages sent by hawkBit
All messages from hawkBit will be sent to the specified exchange in the ``reply_to`` property.
All messages from hawkBit will be sent to the specified exchange in the `reply_to` property.
### Message sent by hawkBit to initialize an update task ### Message sent by hawkBit to initialize an update task
| 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 | Message Properties | Description | Type | Mandatory |
|-----------------------------|----------------------------------|-------------------------------------|---------------- | ------------------ | ------------------------------- | ------ | --------- |
| type | Type of the message | Fixed string "EVENT" | true | content_type | The content type of the payload | String | 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 | false
| Message Properties | Description | Type | Mandatory
|-----------------------------|----------------------------------|-------------------------------------|----------------
| content_type | The content type of the payload | String | true
The Java representation is DownloadAndUpdateRequest: The Java representation is DownloadAndUpdateRequest:
Payload Template Payload Template
```json ```json
{ {
"actionId": long, "actionId": long,
"targetSecurityToken": "String", "targetSecurityToken": "String",
"softwareModules":[ "softwareModules": [
{ {
"moduleId": long, "moduleId": long,
"moduleType":"String", "moduleType": "String",
"moduleVersion":"String", "moduleVersion": "String",
"artifacts":[ "artifacts": [
{ {
"filename":"String", "filename": "String",
"urls":{ "urls": {
"HTTP":"String", "HTTP": "String",
"HTTPS":"String" "HTTPS": "String"
}, },
"hashes":{ "hashes": {
"md5":"String", "md5": "String",
"sha1":"String" "sha1": "String"
}, },
"size":long "size": long
}], }
"metadata":[ ],
{ "metadata": [
"key":"String", {
"value":"String" "key": "String",
} "value": "String"
] }
}] ]
}
]
} }
``` ```
**Example Header and Payload** **Example Header and Payload**
| Headers | MessageProperties | Headers | MessageProperties |
|---------------------------------------|--------------------------------- | --------------------------------------------------------------------------------------- | ----------------------------- |
| type=EVENT <br /> tenant=tenant123 <br /> thingId=abc <br /> topic=DOWNLOAD\_AND\_INSTALL | content_type=application/json | type=EVENT <br /> tenant=tenant123 <br /> thingId=abc <br /> topic=DOWNLOAD_AND_INSTALL | content_type=application/json |
```json ```json
{ {
"actionId":137, "actionId": 137,
"targetSecurityToken":"bH7XXAprK1ChnLfKSdtlsp7NOlPnZAYY", "targetSecurityToken": "bH7XXAprK1ChnLfKSdtlsp7NOlPnZAYY",
"softwareModules":[{ "softwareModules": [
"moduleId":7, {
"moduleType":"firmware", "moduleId": 7,
"moduleVersion":"7.7.7", "moduleType": "firmware",
"artifacts":[ "moduleVersion": "7.7.7",
{ "artifacts": [
"filename":"artifact.zip", {
"urls":{ "filename": "artifact.zip",
"HTTP":"http://download-from-url.com", "urls": {
"HTTPS":"https://download-from-url.com" "HTTP": "http://download-from-url.com",
}, "HTTPS": "https://download-from-url.com"
"hashes":{ },
"md5":"md5hash", "hashes": {
"sha1":"sha1hash" "md5": "md5hash",
}, "sha1": "sha1hash"
"size":512 },
}], "size": 512
"metadata":[ }
{ ],
"key":"installationType", "metadata": [
"value":"5784K#" {
} "key": "installationType",
] "value": "5784K#"
}] }
]
}
]
} }
``` ```

View File

@@ -132,7 +132,6 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
final MessageType messageType = MessageType.valueOf(type); final MessageType messageType = MessageType.valueOf(type);
switch (messageType) { switch (messageType) {
case THING_CREATED: case THING_CREATED:
checkContentTypeJson(message);
setTenantSecurityContext(tenant); setTenantSecurityContext(tenant);
registerTarget(message, virtualHost); registerTarget(message, virtualHost);
break; break;

View File

@@ -121,19 +121,6 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
} }
@Test
@Description("Tests not allowed content-type in message. This message should forwarded to the deadletter queue")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
public void wrongContentType() {
final String controllerId = TARGET_PREFIX + "wrongContentType";
final Message createTargetMessage = createTargetMessage(controllerId, TENANT_EXIST);
createTargetMessage.getMessageProperties().setContentType("WrongContentType");
getDmfClient().send(createTargetMessage);
verifyOneDeadLetterMessage();
assertAllTargetsCount(0);
}
@Test @Test
@Description("Tests null reply to property in message header. This message should forwarded to the deadletter queue") @Description("Tests null reply to property in message header. This message should forwarded to the deadletter queue")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) }) @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })