Skip to content

Commit

Permalink
Add blog post for live message conditions
Browse files Browse the repository at this point in the history
Co-authored-by: David Schwilk <david.schwilk@bosch.io>
Signed-off-by: Stanchev Aleksandar <aleksandar.stanchev@bosch.io>
  • Loading branch information
Aleksandar Stanchev and DerSchwilk committed Nov 3, 2022
1 parent c2c1860 commit 80fb355
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 0 deletions.
5 changes: 5 additions & 0 deletions documentation/src/main/resources/_data/authors.yml
Expand Up @@ -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
@@ -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.

<br/>
<br/>
{% include image.html file="ditto.svg" alt="Ditto" max-width=500 %}
--<br/>
The Eclipse Ditto team

0 comments on commit 80fb355

Please sign in to comment.