| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| <meta name="description" content=""> |
| <meta name="keywords" content="blog, "> |
| <title> E2E acknowledgment </title> |
| |
| <link rel="stylesheet" href="css/syntax.css"> |
| <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" crossorigin="anonymous"> |
| <link rel="stylesheet" href="css/modern-business.css"> |
| <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" crossorigin="anonymous"> |
| <link rel="stylesheet" href="css/customstyles.css"> |
| <link rel="stylesheet" href="css/boxshadowproperties.css"> |
| <link rel="stylesheet" href="css/theme-ditto.css"> |
| <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700"> |
| |
| <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js" crossorigin="anonymous"></script> |
| <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" crossorigin="anonymous"></script> |
| <script src="//cdnjs.cloudflare.com/ajax/libs/anchor-js/2.0.0/anchor.min.js" crossorigin="anonymous"></script> |
| <script src="js/toc.js"></script> |
| <script src="js/customscripts.js"></script> |
| |
| <script type="application/ld+json"> |
| { |
| "@context": "http://schema.org", |
| "@type": "Organization", |
| "url": "https://eclipse.org/ditto/", |
| "logo": "https://eclipse.org/ditto/images/ditto.svg" |
| } |
| </script> |
| |
| <link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16"> |
| <link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32"> |
| <link rel="icon" type="image/png" href="images/favicon-96x96.png" sizes="96x96"> |
| |
| <link rel="alternate" type="application/rss+xml" title="Eclipse Ditto Blog" href="https://www.eclipse.org/ditto/feed.xml"> |
| |
| <!-- Eclipse Foundation cookie consent: --> |
| <link rel="stylesheet" type="text/css" href="//www.eclipse.org/eclipse.org-common/themes/solstice/public/stylesheets/vendor/cookieconsent/cookieconsent.min.css" /> |
| <script src="//www.eclipse.org/eclipse.org-common/themes/solstice/public/javascript/vendor/cookieconsent/default.min.js"></script> |
| |
| <script> |
| $(document).ready(function() { |
| $("#tg-sb-link").click(function() { |
| $("#tg-sb-sidebar").toggle(); |
| $("#tg-sb-content").toggleClass('col-md-9'); |
| $("#tg-sb-content").toggleClass('col-md-12'); |
| $("#tg-sb-icon").toggleClass('fa-toggle-on'); |
| $("#tg-sb-icon").toggleClass('fa-toggle-off'); |
| }); |
| }); |
| </script> |
| </head> |
| |
| |
| <script> |
| (function(w,d,s,l,i){ |
| w[l]=w[l]||[]; |
| w[l].push({'gtm.start': |
| new Date().getTime(),event:'gtm.js'}); |
| var f=d.getElementsByTagName(s)[0], |
| j=d.createElement(s), |
| dl=l!='dataLayer'?'&l='+l:''; |
| j.async=true; |
| j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl; |
| f.parentNode.insertBefore(j,f); |
| })(window,document,'script','dataLayer','GTM-5WLCZXC'); |
| </script> |
| |
| |
| |
| <body> |
| <!-- Navigation --> |
| <nav class="navbar navbar-inverse navbar-fixed-top"> |
| <div class="container topnavlinks"> |
| <div class="navbar-header"> |
| <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> |
| <span class="sr-only">Toggle navigation</span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| </button> |
| <a class="navbar-ditto-home" href="index.html"> <img src="images/ditto_allwhite_symbolonly.svg" class="ditto-navbar-symbol" alt="Home"> <img src="images/ditto_allwhite_textonly.svg" class="ditto-navbar-symbol-text" alt="Ditto"></a> |
| </div> |
| <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> |
| <ul class="nav navbar-nav navbar-right"> |
| <!-- toggle sidebar button --> |
| <!--<li><a id="tg-sb-link" href="#"><i id="tg-sb-icon" class="fa fa-toggle-on"></i> Nav</a></li>--> |
| <!-- entries without drop-downs appear here --> |
| |
| |
| |
| |
| |
| |
| |
| <li><a href="blog.html">Blog</a></li> |
| |
| |
| |
| <li><a href="intro-overview.html">Documentation</a></li> |
| |
| |
| |
| <li><a href="http-api-doc.html">HTTP API</a></li> |
| |
| |
| |
| <li><a href="sandbox.html">Sandbox</a></li> |
| |
| |
| |
| <li><a href="https://github.com/eclipse/ditto" target="_blank">GitHub</a></li> |
| |
| |
| |
| <li><a href="https://github.com/eclipse/ditto-examples" target="_blank">GitHub examples</a></li> |
| |
| |
| |
| <!-- entries with drop-downs appear here --> |
| <!-- conditional logic to control which topnav appears for the audience defined in the configuration file.--> |
| |
| |
| <li class="dropdown"> |
| <a href="#" class="dropdown-toggle" data-toggle="dropdown">Links<b class="caret"></b></a> |
| <ul class="dropdown-menu"> |
| |
| |
| <li><a href="https://projects.eclipse.org/projects/iot.ditto" target="_blank">Eclipse Ditto Project</a></li> |
| |
| |
| |
| <li><a href="https://www.eclipse.org/forums/index.php/f/364/" target="_blank">Forum</a></li> |
| |
| |
| |
| <li><a href="https://ci.eclipse.org/ditto/" target="_blank">Jenkins</a></li> |
| |
| |
| |
| <li><a href="https://dev.eclipse.org/mhonarc/lists/ditto-dev/" target="_blank">Mailing list archives</a></li> |
| |
| |
| |
| <li><a href="https://gitter.im/eclipse/ditto" target="_blank">Gitter.im chat</a></li> |
| |
| |
| </ul> |
| </li> |
| |
| |
| |
| <!--comment out this block if you want to hide search--> |
| <li> |
| <!--start search--> |
| <div id="search-demo-container"> |
| <input type="text" id="search-input" placeholder="search..."> |
| <ul id="results-container"></ul> |
| </div> |
| <script src="//cdnjs.cloudflare.com/ajax/libs/simple-jekyll-search/0.0.9/jekyll-search.js" type="text/javascript"></script> |
| <script type="text/javascript"> |
| SimpleJekyllSearch.init({ |
| searchInput: document.getElementById('search-input'), |
| resultsContainer: document.getElementById('results-container'), |
| dataSource: 'search.json', |
| searchResultTemplate: '<li><a href="{url}" title="E2E acknowledgment">{title}</a></li>', |
| noResultsText: 'No results found.', |
| limit: 10, |
| fuzzy: true, |
| }) |
| </script> |
| <!--end search--> |
| </li> |
| </ul> |
| </div> |
| </div> |
| <!-- /.container --> |
| </nav> |
| |
| <!-- Page Content --> |
| <div class="container"> |
| <div id="main"> |
| <!-- Content Row --> |
| <div class="row"> |
| |
| |
| |
| <!-- Content Column --> |
| <div class="col-md-12" id="tg-sb-content"> |
| <!-- Look the author details up from the site config. --> |
| |
| |
| <!-- Output author details if some exist. --> |
| <!-- Output author details if some exist. --> |
| <!----> |
| <!--<span>--> |
| <!--<!– Mugshot. –>--> |
| <!--<img src="https://www.gravatar.com/avatar/d2b4eba8f1c947a3fb94be23d8b82d8b?s=135" alt="A photo of Yannic Klem" />--> |
| |
| <!--<!– Personal Info. –>--> |
| <!--Written by <a href="https://github.com/Yannic92" target="_blank">Yannic Klem</a>--> |
| <!--</span>--> |
| <!----> |
| |
| <article class="post" itemscope itemtype="http://schema.org/BlogPosting"> |
| |
| <header class="post-header"> |
| <h1 class="post-title" itemprop="name headline">E2E acknowledgment</h1> |
| <p class="post-meta">Published by <img src="https://www.gravatar.com/avatar/d2b4eba8f1c947a3fb94be23d8b82d8b?s=135" alt="A photo of Yannic Klem" style="width:50px;border-radius:50%;display:inline-block;margin-right:5px;" /><span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name"><a href="https://github.com/Yannic92" target="_blank">Yannic Klem</a> </span></span> on <time datetime="2020-10-23T00:00:00+00:00" itemprop="datePublished">Oct 23, 2020</time> - Tags: |
| |
| |
| |
| <a href="tag_blog.html">blog</a> |
| |
| |
| |
| |
| </p> |
| |
| |
| </header> |
| |
| <div class="post-content" itemprop="articleBody"> |
| |
| |
| |
| |
| |
| <!-- this handles the automatic toc. use ## for subheads to auto-generate the on-page minitoc. if you use html tags, you must supply an ID for the heading element in order for it to appear in the minitoc. --> |
| <script> |
| $( document ).ready(function() { |
| // Handler for .ready() called. |
| |
| $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3,h4' }); |
| |
| /* this offset helps account for the space taken up by the floating toolbar. */ |
| $('#toc').on('click', 'a', function() { |
| var target = $(this.getAttribute('href')) |
| , scroll_target = target.offset().top |
| |
| $(window).scrollTop(scroll_target - 10); |
| return false |
| }) |
| |
| }); |
| </script> |
| |
| <div id="toc"></div> |
| |
| |
| |
| <h2 id="e2e-acknowledgement-using-eclipse-ditto">E2E acknowledgement using Eclipse Ditto</h2> |
| |
| <p>By adding the new <a href="basic-acknowledgements.html">acknowledgements feature</a> to Ditto, it is now possible to provide an end to end QoS (quality of service) with level 1. |
| Previously the <a href="architecture-services-connectivity.html">connectivity service</a> of Ditto did accept all incoming messages immediately as soon as it received the message.</p> |
| |
| <p>This behaviour can now be controlled by a Ditto header called <a href="basic-acknowledgements.html#requesting-acks"><code class="highlighter-rouge">requested-acks</code></a>.</p> |
| |
| <p>In this blog post I will provide a few examples for how to use this new feature in the following scenarios:</p> |
| |
| <ol> |
| <li>Device publishes a change of its state and doesn’t care about whether the event regarding this change will be received by any subscriber or not.<br /> |
| This is the <a href="#scenario-1---fire-and-forget">fire and forget</a> scenario.</li> |
| <li>Device publishes a change of its state and wants to be sure it is persisted in Ditto.<br /> |
| This is the <a href="#scenario-2---processed-in-ditto">processed in Ditto</a> scenario.</li> |
| <li>Device publishes a change of its state and wants to be sure an application connected to Eclipse Ditto will receive the event regarding this change of the state.<br /> |
| This is the <a href="#scenario-3---notification-scenario">notification</a> scenario.</li> |
| <li>Device publishes a change of its state and wants to be notified when a subscriber was not able to receive the event regarding this change.<br /> |
| This is the <a href="#scenario-4---tracked-notification-scenario">tracked notification</a> scenario.</li> |
| <li>Device sends a live message and wants to be sure that it will eventually receive a response.<br /> |
| This is the <a href="#scenario-5---long-running-live-message-scenario">long running live message</a> scenario.</li> |
| <li>Device sends a live message and wants to either receive the response within a given timeout or never.<br /> |
| This is the <a href="#scenario-6---asking-for-required-information-scenario">asking for required information</a> scenario.</li> |
| </ol> |
| |
| <h2 id="scenarios">Scenarios</h2> |
| |
| <p>The following scenarios all share the same context:</p> |
| <ul> |
| <li>a device sends data/messages via a device connectivity layer (e.g. <a href="https://eclipse.org/hono/">Eclipse Hono</a> or an MQTT broker) to Ditto</li> |
| <li>Ditto’s <a href="architecture-services-connectivity.html">connectivity service</a> |
| <ul> |
| <li>consumes the <a href="protocol-specification.html">Ditto Protocol</a> message</li> |
| <li>forwards the message into the Ditto cluster to be processed</li> |
| <li>is responsible for technically acknowledging/settling the consumed message at the device connectivity layer / broker |
| <ul> |
| <li>the strategy of when this is done and with which outcome is handled by the Ditto headers mentioned in the scenarios</li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| |
| <p>Although all scenarios are based on the device sending something (e.g. telemetry data or a message), the |
| E2E acknowledgement can also be used the other way around when e.g. a backend application sends something to a device.</p> |
| |
| <h3 id="scenario-1---fire-and-forget">Scenario 1 - Fire and Forget</h3> |
| |
| <p>This is the simplest scenario of all, since the change can be published in a fire and forget semantics.</p> |
| |
| <p>In this scenario the device will send the modification command containing the headers:</p> |
| <ul> |
| <li><code class="highlighter-rouge">response-required=false</code></li> |
| <li><code class="highlighter-rouge">requested-acks=[]</code></li> |
| </ul> |
| |
| <p>Example <a href="protocol-specification.html">Ditto Protocol</a> message:</p> |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> |
| </span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/my-thing/things/twin/commands/modify"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> |
| </span><span class="s2">"response-required"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"requested-acks"</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span><span class="w"> |
| </span><span class="p">},</span><span class="w"> |
| </span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/features/lightSwitch/properties/status"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"on"</span><span class="w"> |
| </span><span class="p">}</span><span class="w"> |
| </span></code></pre></div></div> |
| |
| <p>For this case the connectivity service will immediately acknowledge the incoming message at the messaging system and then continues to process the command.</p> |
| |
| <p>It doesn’t matter if the command could be processed successfully or if any subscriber received an event for this change.</p> |
| |
| <h3 id="scenario-2---processed-in-ditto">Scenario 2 - Processed in Ditto</h3> |
| |
| <p>For this scenario the device wants to be sure its change will be properly persisted in Ditto.</p> |
| |
| <p>The command needs to define the following headers:</p> |
| <ul> |
| <li><code class="highlighter-rouge">response-required=false</code></li> |
| <li><code class="highlighter-rouge">requested-acks=["twin-persisted"]</code></li> |
| </ul> |
| |
| <p>Example <a href="protocol-specification.html">Ditto Protocol</a> message:</p> |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> |
| </span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/my-thing/things/twin/commands/modify"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> |
| </span><span class="s2">"response-required"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"requested-acks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"twin-persisted"</span><span class="p">]</span><span class="w"> |
| </span><span class="p">},</span><span class="w"> |
| </span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/features/lightSwitch/properties/status"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"on"</span><span class="w"> |
| </span><span class="p">}</span><span class="w"> |
| </span></code></pre></div></div> |
| |
| <p>For this case the connectivity service will wait until the modification will be properly persisted in Ditto before acknowledging the incoming message at the messaging system.</p> |
| |
| <p>If the device published this command for example via an AMQP broker (with a QoS 1 “at least once” semantic), |
| this will cause the broker to redeliver the command to Ditto if the acknowledgment fails.<br /> |
| Please be aware that a redelivery will only be requested for the following error status codes:</p> |
| <ul> |
| <li><code class="highlighter-rouge">408</code> (Request timed out)</li> |
| <li><code class="highlighter-rouge">424</code> (Dependency Failure)</li> |
| <li>All kinds of <code class="highlighter-rouge">5xx</code> status codes</li> |
| </ul> |
| |
| <p>In this scenario it does matter if the command could be processed successfully, but it’s still not relevant if any subscriber received an event for this change.</p> |
| |
| <h3 id="scenario-3---notification-scenario">Scenario 3 - Notification scenario</h3> |
| |
| <p>For this scenario the device wants to be sure another system will be notified about the change of its state.</p> |
| |
| <p>This could be for example an alarming system which wants to be sure a backend application receives the information that the alarm was triggered.</p> |
| |
| <p>A prerequisite for this is that any kind of connection exists that publishes the event to the backend application and declares a user defined acknowledgement label. |
| This can be a <a href="httpapi-protocol-bindings-websocket.html">WebSocket session</a> or any kind of Ditto Connection types which can be found <a href="connectivity-overview.html">here</a>.</p> |
| |
| <p>For this example we expect the event to be forwarded by an <a href="connectivity-protocol-bindings-http.html">HTTP connection</a> |
| which declared the following acknowledgement label as |
| <a href="basic-connections.html#target-issued-acknowledgement-label">issued acknowledgement of the target</a>: <code class="highlighter-rouge">d45d4522-142e-4057-ae87-8969343a3ddc:backend-processed</code>.</p> |
| |
| <p>The UUID prefix in this case is the ID of the HTTP connection and the<code class="highlighter-rouge">backend-process</code> part is a custom label, defined by the user.</p> |
| |
| <p>The command needs to define the following headers:</p> |
| <ul> |
| <li><code class="highlighter-rouge">response-required=false</code></li> |
| <li><code class="highlighter-rouge">requested-acks=["d45d4522-142e-4057-ae87-8969343a3ddc:backend-processed"]</code></li> |
| <li><code class="highlighter-rouge">timeout=30s</code> (optional. Default is 10s.)</li> |
| </ul> |
| |
| <p>Example <a href="protocol-specification.html">Ditto Protocol</a> message:</p> |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> |
| </span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/my-thing/things/twin/commands/modify"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> |
| </span><span class="s2">"response-required"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"requested-acks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"d45d4522-142e-4057-ae87-8969343a3ddc:backend-processed"</span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"timeout"</span><span class="p">:</span><span class="w"> </span><span class="s2">"30s"</span><span class="w"> |
| </span><span class="p">},</span><span class="w"> |
| </span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/features/alarm/properties/status"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"on"</span><span class="w"> |
| </span><span class="p">}</span><span class="w"> |
| </span></code></pre></div></div> |
| |
| <p>For this case the connectivity service will wait until the HTTP request, which forwards the event regarding the thing change, |
| will be finished before acknowledging the incoming message at the messaging system.</p> |
| |
| <p>The status code of the HTTP response will in this case determine if the message will be acknowledged successfully or not and if a redelivery will be requested or not.<br /> |
| All kinds of <code class="highlighter-rouge">2xx</code> status codes will lead to a successful acknowledgement at the messaging system.<br /> |
| All other status codes will lead to a failed acknowledgement at the messaging system and for the following status codes a redelivery will be requested:</p> |
| <ul> |
| <li><code class="highlighter-rouge">408</code> (Request timed out)</li> |
| <li><code class="highlighter-rouge">424</code> (Dependency Failure)</li> |
| <li>All kinds of <code class="highlighter-rouge">5xx</code> status codes</li> |
| </ul> |
| |
| <p>In this scenario it is ensured a specified subscriber will receive an event for this change.</p> |
| |
| <h3 id="scenario-4---tracked-notification-scenario">Scenario 4 - Tracked notification scenario</h3> |
| |
| <p>For this scenario the device wants to know when a system could not be notified about the change of its state.</p> |
| |
| <p>This could be for example an alarming system which wants to be sure a backend application receives the information, |
| or if not: tries to send an SMS as notification.</p> |
| |
| <p>This scenario is mostly like scenario 3, but needs to set the <code class="highlighter-rouge">response-required</code> header to <code class="highlighter-rouge">true</code> and it’s required |
| to <a href="basic-connections.html#source-reply-target">configure the reply-target of the source</a> to also expect “nack” responses.</p> |
| |
| <p>Example <a href="protocol-specification.html">Ditto Protocol</a> message:</p> |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> |
| </span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/my-thing/things/twin/commands/modify"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> |
| </span><span class="s2">"response-required"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"requested-acks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"d45d4522-142e-4057-ae87-8969343a3ddc:backend-processed"</span><span class="p">]</span><span class="w"> |
| </span><span class="p">},</span><span class="w"> |
| </span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/features/alarm/properties/status"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"on"</span><span class="w"> |
| </span><span class="p">}</span><span class="w"> |
| </span></code></pre></div></div> |
| |
| <p>In this case the device will receive an acknowledgement response containing the status code and payload of the response of the backend application.<br /> |
| Based on this the device can decide how to handle the situation.<br /> |
| It is suggested to publish the modification command with QoS 0 (“at most once” semantics) in this case because the |
| device handles the result of the E2E acknowledgement. With QoS 1 (“at least once” semantics) brokers would usually redeliver the message to Ditto.</p> |
| |
| <p>If the HTTP endpoint of the backend application responds with the following response:</p> |
| |
| <p>headers:</p> |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"content-type": "application/json" |
| </code></pre></div></div> |
| |
| <p>body:</p> |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> |
| </span><span class="s2">"errorCode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"notification.smartphone.failed"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Could not notify smartphone."</span><span class="w"> |
| </span><span class="p">}</span><span class="w"> |
| </span></code></pre></div></div> |
| |
| <p>status code: <code class="highlighter-rouge">424</code></p> |
| |
| <p>The response received at the device would look like this:</p> |
| |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> |
| </span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/my-thing/things/twin/acks/d45d4522-142e-4057-ae87-8969343a3ddc:backend-processed"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> |
| </span><span class="s2">"response-required"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"requested-acks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"d45d4522-142e-4057-ae87-8969343a3ddc:backend-processed"</span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"timeout"</span><span class="p">:</span><span class="w"> </span><span class="s2">"30s"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"content-type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"application/json"</span><span class="w"> |
| </span><span class="p">},</span><span class="w"> |
| </span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> |
| </span><span class="s2">"errorCode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"notification.smartphone.failed"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Could not notify smartphone."</span><span class="w"> |
| </span><span class="p">},</span><span class="w"> |
| </span><span class="s2">"status"</span><span class="p">:</span><span class="w"> </span><span class="mi">424</span><span class="w"> |
| </span><span class="p">}</span><span class="w"> |
| </span></code></pre></div></div> |
| |
| <h3 id="scenario-5---long-running-live-message-scenario">Scenario 5 - Long running live message scenario</h3> |
| |
| <p>For this scenario the device is going to ask for an information which it needs eventually.</p> |
| |
| <p>Let’s say the device asks for the endpoint where it should download the new firmware from.<br /> |
| It’s not required that this response arrives within a given time. It’s just required to eventually arrive at the device |
| and after it was received the device can signal the user, that it is ready to download the firmware.</p> |
| |
| <p>The headers of the live message should have the following values:</p> |
| <ul> |
| <li><code class="highlighter-rouge">response-required=true</code></li> |
| <li><code class="highlighter-rouge">requested-acks=["live-response"]</code></li> |
| </ul> |
| |
| <p>Example <a href="protocol-specification.html">Ditto Protocol</a> message:</p> |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> |
| </span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/my-thing/things/live/messages/firmware"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> |
| </span><span class="s2">"response-required"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"requested-acks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"live-response"</span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"content-type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text/plain"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"timeout"</span><span class="p">:</span><span class="w"> </span><span class="s2">"5s"</span><span class="w"> |
| </span><span class="p">},</span><span class="w"> |
| </span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/outbox/messages/firmware"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"firmware.url.query"</span><span class="w"> |
| </span><span class="p">}</span><span class="w"> |
| </span></code></pre></div></div> |
| |
| <p>By requesting the acknowledgement <code class="highlighter-rouge">live-response</code> the connectivity service will wait until the response for the live message arrived |
| for 5s before acknowledging the incoming message at the broker and will request a redelivery if the response did not arrive within this timeout.</p> |
| |
| <p>This will repeat until either the broker discards the message or the response arrives in the specified timeout. |
| That way it is guaranteed that the device will eventually receive the response.</p> |
| |
| <h3 id="scenario-6---asking-for-required-information-scenario">Scenario 6 - Asking for required information scenario</h3> |
| |
| <p>For this scenario the device is going to ask for an information which it needs right now to proceed with its current task.</p> |
| |
| <p>Let’s say the device asks if it should allow a car with a license plate it detected to drive on the property by opening the barrier. |
| It could be possible to ask for that information, so the barrier opens automatically, but providing a fallback mechanism |
| like entering a code directly at the device if this response does not arrive within time.</p> |
| |
| <p>The headers of the live message should have the following values:</p> |
| <ul> |
| <li><code class="highlighter-rouge">response-required=true</code></li> |
| <li><code class="highlighter-rouge">requested-acks=[]</code></li> |
| </ul> |
| |
| <p>Example <a href="protocol-specification.html">Ditto Protocol</a> message:</p> |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> |
| </span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/my-thing/things/live/messages/car-enter"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> |
| </span><span class="s2">"response-required"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"requested-acks"</span><span class="p">:</span><span class="w"> </span><span class="p">[],</span><span class="w"> |
| </span><span class="s2">"content-type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text/plain"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"timeout"</span><span class="p">:</span><span class="w"> </span><span class="s2">"5s"</span><span class="w"> |
| </span><span class="p">},</span><span class="w"> |
| </span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/outbox/messages/car-enter"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"FN IB 1337"</span><span class="w"> |
| </span><span class="p">}</span><span class="w"> |
| </span></code></pre></div></div> |
| |
| <p>By requesting explicitly not requesting any acknowledgement but still requiring a response, the connectivity service will |
| immediately acknowledge the incoming message at the broker. The device will then either receive the response within the specified timeout or never. |
| So the device can provide its alternative options to open the barrier after 5 seconds.</p> |
| |
| <h2 id="we-embrace-your-feedback">We embrace your feedback</h2> |
| |
| <p>I hope I could demonstrate the power of the new acknowledgement feature properly and could make it clear how it can be used. |
| Maybe you did recognize some of your use cases in the given examples or maybe you have another use case which can or cannot be solved by this feature.</p> |
| |
| <p>We would love to get your <a href="feedback.html">feedback</a>.</p> |
| |
| <p><br /> |
| <br /></p> |
| <figure><img class="docimage" src="images/ditto.svg" alt="Ditto" style="max-width: 500px" /></figure> |
| |
| <p>–<br /> |
| The Eclipse Ditto team</p> |
| |
| </div> |
| |
| |
| |
| </article> |
| |
| <hr class="shaded"/> |
| |
| <footer> |
| <div class="row"> |
| <div class="col-lg-12 footer"> |
| <div class="logo"> |
| <a href="https://eclipse.org"><img src="images/eclipse_foundation_logo.svg" alt="Eclipse logo"/></a> |
| </div> |
| <p class="notice"> |
| ©2021 Eclipse Ditto. |
| Site last generated: Feb 22, 2021 <br /> |
| </p> |
| <div class="quickLinks"> |
| <a href="https://www.eclipse.org/legal/privacy.php" target="_blank"> |
| > Privacy Policy |
| </a> |
| <a href="https://www.eclipse.org/legal/termsofuse.php" target="_blank"> |
| > Terms of Use |
| </a> |
| <a href="https://www.eclipse.org/legal/copyright.php" target="_blank"> |
| > Copyright Agent |
| </a> |
| <a href="https://www.eclipse.org/legal" target="_blank"> |
| > Legal |
| </a> |
| <a href="https://www.eclipse.org/legal/epl-2.0/" target="_blank"> |
| > License |
| </a> |
| <a href="https://eclipse.org/security" target="_blank"> |
| > Report a Vulnerability |
| </a> |
| </div> |
| </div> |
| </div> |
| </footer> |
| |
| |
| </div> |
| <!-- /.row --> |
| </div> |
| <!-- /.container --> |
| </div> |
| <!-- /#main --> |
| </div> |
| |
| </body> |
| </html> |