diff --git a/documentation/src/main/resources/_data/authors.yml b/documentation/src/main/resources/_data/authors.yml index 41700dcf78..93333c8d44 100644 --- a/documentation/src/main/resources/_data/authors.yml +++ b/documentation/src/main/resources/_data/authors.yml @@ -57,3 +57,8 @@ vadim_guenther: name: Vadim Günther email: vadim.guenther@bosch.io web: https://github.com/VadimGue + +aleksandar_stanchev: + name: Aleksandar Stanchev + email: aleksandar.stanchev@bosch.io + web: https://github.com/alstanchev diff --git a/documentation/src/main/resources/_posts/2022-10-30-live-message-conditions.md b/documentation/src/main/resources/_posts/2022-10-30-live-message-conditions.md new file mode 100644 index 0000000000..dc66aa2e62 --- /dev/null +++ b/documentation/src/main/resources/_posts/2022-10-30-live-message-conditions.md @@ -0,0 +1,162 @@ +--- +title: "Support conditional requests for live messages" +published: true +permalink: 2022-10-30-live-message-conditions.html +layout: post +author: aleksandar_stanchev +tags: [blog, http, protocol, rql] +hide_sidebar: true +sidebar: false +toc: true +--- + +With the upcoming release of Eclipse Ditto **version 3.1.0** it will be possible to process live messages based on +conditions. + +## Conditional live messages +Ditto now supports conditional message sending based on a specified condition in the request. +This functionality can be used via the HTTP API with an HTTP header or query parameter, as well as via the Ditto protocol, +and the Ditto Java Client. +For all three ways there is an example provided in this blog post. + +This turns useful, if you want for example to send a message to your device, but only if its digital twin has a specific attribute set. + +To be more concrete let's say we have a thing with an attribute _temperature_, and we only want to +send an alarm live message to the corresponding device, if the temperature of the thing is over 60 degrees. +To achieve this the following HTTP request can be used: + +``` +PUT /api/2/things/org.eclipse.ditto:coffeebrewer/inbox/mesages/tempreatureAlarm?condition=gt(attributes/temperature,60) +alarm! +``` + +Conditions can be specified using [RQL syntax](basic-rql.html) to check if a thing has a specific attribute +or feature property value. + +In case the condition does not match to the actual state of the thing, the request will fail with +HTTP status code **412 - Precondition Failed**. And the message will not be processed. + +If the given condition is invalid, the request will fail with HTTP status code **400 - Bad Request**. + +More documentation for this feature can be found here: [Conditional Requests](basic-conditional-requests.html) + +### Permissions for conditional requests + +In order to execute a conditional request, the authorized subject needs to have WRITE permission at the resource +that should be changed by the request. + +Additionally, the authorized subject needs to have READ permission at the resource used in the specified condition. +Given the condition from the introduction `condition=eq(attributes/location,"Wonderland")`, +read access on the single attribute would be sufficient. +However, the condition can also be more complex, or include other sub-structures of the thing. +Then of course, the authorized subject needs READ permission on all parameters of the specified condition. + +## Examples +The following sub-sections will show how to use conditional requests via the HTTP API, the Ditto protocol, +and the Ditto Java Client. + +To demonstrate the new conditional request, we assume that the following thing already exists: + +```json +{ + "thingId": "org.eclipse.ditto:carbon-monoxide-alarm", + "policyId": "org.eclipse.ditto:carbon-monoxide-alarm", + "attributes": { + "manufacturer": "ACME demo corp.", + "location": "Wonderland", + "serialno": "42" + }, + "features": { + "carbon-monoxide-level": { + "properties": { + "ppm,": 2 + } + }, + "alarm": { + "properties": { + "lastTriggered": "2021-09-23T07:01:56Z", + "confirmed": false + } + } + } + } +} +``` + +### Condition based on alarm/confirmed +In this example a live alarm message from the device should only be sent, if the alarm confirmed property is set to +false by the end user application. This is done to prevent duplicate received alarms by the customer. + +Another use case could be to i.e. only send a message to a device when the device is connected: +``` +POST /api/2/things/org.eclipse.ditto:my-thing-1/inbox/messages/doSomething?condition=gt(features/ConnectionStatus/properties/status/readyUntil,time:now) +``` + +### Permissions to execute the example +For this example, the authorized subject could have READ and WRITE permissions on the complete thing resource. +However, it is only necessary on the path _thing:/features/alarm/properties/confirmed_. + +## Conditional requests via HTTP API +Using the HTTP API the condition can either be specified via HTTP Header or via HTTP query parameter. +In this section, we will show how to use both options. + +### Conditional request with HTTP Header +``` +curl -X PATCH -H 'Content-Type: application/json' -H 'condition: eq(features/alarm/properties/confirmed/,false)' /api/2/things/org.eclipse.ditto:carbon-monoxide-alarm/outbox/messages/co-alarm -d '{ "CO Level to high! Open your windows!" }' +``` + +### Conditional request with HTTP query parameter +``` +curl -X PATCH -H 'Content-Type: application/json' /api/2/things/org.eclipse.ditto:carbon-monoxide-alarm/outbox/messages/co-alarm?eq(features/alarm/properties/confirmed/,false) -d '{ "CO Level to high! Open your windows!" }' +``` + +## Conditional request via Ditto protocol +It is also possible to use conditional requests via the Ditto protocol. +Applying the following Ditto command to the existing thing will lead to the same result as in the above HTTP example. + +```json +{ + "topic": "org.eclipse.ditto:carbon-monoxide-alarm/things/live/messages/co-alarm", + "headers": { + "content-type": "application/json", + "condition": "eq(features/alarm/properties/confirmed/,false)" + }, + "path": "/outbox/messages/co-alarm", + "value": "CO Level to high! Open your windows!" +} +``` + +## Using conditional requests in the Ditto Java Client +The conditional requests are also supported via the [Ditto Java Client](client-sdk-java.html) +with the upcoming (**Ditto Java Client version 3.1.0**). + +Example for a conditional update of a thing with the Ditto Java client: + +```java +String thingId = "org.eclipse.ditto:carbon-monoxide-alarm"; + +// initialize the ditto-client +DittoClient dittoClient = ... ; + +dittoClient.live().message(Options.condition("eq(features/alarm/properties/confirmed/,false)")) + .from(thingId) + .subject("co-alarm") + .payload("CO Level to high! Open your windows!") + .send(String.class, (response, throwable) -> { + if (throwable != null) { + LOGGER.error("Received error while sending conditional update: '{}' ", throwable.toString()); + } else { + LOGGER.info("Received response for conditional update: '{}'", response); + } +}); +``` + +## Feedback? + +Please [get in touch](feedback.html) if you have feedback or questions towards this new functionality. + +
+
+{% include image.html file="ditto.svg" alt="Ditto" max-width=500 %} +--
+The Eclipse Ditto team