blob: cae848f96ca97f3839714ce9585f6eeeb5a6b050 [file] [log] [blame]
<!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="model, acks, acknowledgement, acknowledgements, qos, at least once, delivery, guarantee">
<title> Acknowledgements / Quality of Service • Eclipse Ditto™ • a digital twin framework</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">&nbsp;<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="Eclipse 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">
<img src="images/GitHub-Mark-Light-32px.png" alt="Sources at GitHub">
</a></li>
<li><a href="https://github.com/eclipse/ditto-clients" target="_blank">
<img src="images/GitHub-Mark-Light-32px.png" alt="SDK sources at GitHub">SDKs
</a></li>
<li><a href="https://github.com/eclipse/ditto-examples" target="_blank">
<img src="images/GitHub-Mark-Light-32px.png" alt="Example sources at 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="Acknowledgements / Quality of Service">{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">
<!-- Sidebar Column -->
<div class="col-md-3" id="tg-sb-sidebar">
<ul id="mysidebar" class="nav">
<li class="sidebarTitle">
<label for="docVersion">Eclipse Ditto™ version:</label>
<div class="select-wrapper">
<select id="docVersion" name="docVersion">
<option value="">development</option>
<option value="2.0">2.0</option>
<option value="1.5">1.5</option>
<option value="1.4">1.4</option>
<option value="1.3">1.3</option>
<option value="1.2">1.2</option>
<option value="1.1">1.1</option>
<option value="1.0">1.0</option>
</select>
</div>
<div id="dev-warning">
<div markdown="span" class="alert alert-warning" role="alert" style="font-size:0.6em"><i class="fa fa-warning"></i> <b>Important:</b> This documentation reflects the latest 'development'. You might want to choose a released version.</div>
</div>
</li>
<li class="subfolders">
<a href="#"><span></span>Introduction</a>
<ul>
<li><a href="intro-overview.html">Overview</a></li>
<li><a href="intro-digitaltwins.html">Digital twins</a></li>
<li><a href="intro-hello-world.html">Hello world</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Release Notes</a>
<ul>
<li><a href="release_notes_201.html">2.0.1</a></li>
<li><a href="release_notes_200.html">2.0.0</a></li>
<li><a href="release_notes_151.html">1.5.1</a></li>
<li><a href="release_notes_150.html">1.5.0</a></li>
<li class="subfolders">
<a href="#"><span></span>Archive</a>
<ul>
<li><a href="release_notes_140.html">1.4.0</a></li>
<li><a href="release_notes_130.html">1.3.0</a></li>
<li><a href="release_notes_121.html">1.2.1</a></li>
<li><a href="release_notes_120.html">1.2.0</a></li>
<li><a href="release_notes_115.html">1.1.5</a></li>
<li><a href="release_notes_113.html">1.1.3</a></li>
<li><a href="release_notes_112.html">1.1.2</a></li>
<li><a href="release_notes_111.html">1.1.1</a></li>
<li><a href="release_notes_110.html">1.1.0</a></li>
<li><a href="release_notes_100.html">1.0.0</a></li>
<li><a href="release_notes_090.html">0.9.0</a></li>
<li><a href="release_notes_080.html">0.8.0</a></li>
<li><a href="release_notes_100-M2.html">1.0.0-M2</a></li>
<li><a href="release_notes_100-M1a.html">1.0.0-M1a</a></li>
<li><a href="release_notes_090-M2.html">0.9.0-M2</a></li>
<li><a href="release_notes_090-M1.html">0.9.0-M1</a></li>
<li><a href="release_notes_080-M3.html">0.8.0-M3</a></li>
<li><a href="release_notes_080-M2.html">0.8.0-M2</a></li>
<li><a href="release_notes_080-M1.html">0.8.0-M1</a></li>
<li><a href="release_notes_030-M2.html">0.3.0-M2</a></li>
<li><a href="release_notes_030-M1.html">0.3.0-M1</a></li>
<li><a href="release_notes_020-M1.html">0.2.0-M1</a></li>
<li><a href="release_notes_010-M3.html">0.1.0-M3</a></li>
<li><a href="release_notes_010-M1.html">0.1.0-M1</a></li>
</ul>
</li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Installation</a>
<ul>
<li><a href="installation-building.html">Building Ditto</a></li>
<li><a href="installation-running.html">Running Ditto</a></li>
<li><a href="installation-operating.html">Operating Ditto</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Basic concepts</a>
<ul>
<li><a href="basic-overview.html">Overview</a></li>
<li class="subfolders">
<a href="#"><span></span>Model entities</a>
<ul>
<li><a href="basic-thing.html">Thing</a></li>
<li><a href="basic-feature.html">Feature</a></li>
<li><a href="basic-policy.html">Policy</a></li>
<li><a href="basic-namespaces-and-names.html">Namespaces and Names</a></li>
<li><a href="basic-metadata.html">Thing Metadata</a></li>
<li><a href="basic-errors.html">Errors</a></li>
</ul>
</li>
<li><a href="basic-auth.html">Authentication and Authorization</a></li>
<li><a href="basic-messages.html">Messages</a></li>
<li><a href="basic-signals.html">Signals</a></li>
<li class="subfolders">
<a href="#"><span></span>Signal types</a>
<ul>
<li><a href="basic-signals-command.html">Command</a></li>
<li><a href="basic-signals-commandresponse.html">Command response</a></li>
<li><a href="basic-signals-errorresponse.html">Error response</a></li>
<li><a href="basic-signals-event.html">Event</a></li>
<li><a href="basic-signals-announcement.html">Announcement</a></li>
</ul>
</li>
<li><a href="basic-apis.html">APIs</a></li>
<li><a href="basic-connections.html">Connections</a></li>
<li><a href="basic-placeholders.html">Placeholders</a></li>
<li><a href="basic-changenotifications.html">Change notifications</a></li>
<li><a href="basic-rql.html">RQL expressions</a></li>
<li><a href="basic-enrichment.html">Signal enrichment</a></li>
<li><a href="basic-search.html">Search</a></li>
<li class="active"><a href="basic-acknowledgements.html">Acknowledgements / QoS</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Advanced concepts</a>
<ul>
<li><a href="advanced-data-by-pass.html">Data By-Pass</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Architecture</a>
<ul>
<li><a href="architecture-overview.html">Overview</a></li>
<li class="subfolders">
<a href="#"><span></span>Services</a>
<ul>
<li><a href="architecture-services-policies.html">Policies</a></li>
<li><a href="architecture-services-things.html">Things</a></li>
<li><a href="architecture-services-things-search.html">Things-Search</a></li>
<li><a href="architecture-services-connectivity.html">Connectivity</a></li>
<li><a href="architecture-services-concierge.html">Concierge</a></li>
<li><a href="architecture-services-gateway.html">Gateway</a></li>
</ul>
</li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>HTTP API</a>
<ul>
<li><a href="httpapi-overview.html">Overview</a></li>
<li><a href="httpapi-concepts.html">Concepts</a></li>
<li><a href="httpapi-search.html">Search</a></li>
<li><a href="httpapi-messages.html">Messages</a></li>
<li><a href="httpapi-protocol-bindings-websocket.html">WebSocket protocol binding</a></li>
<li><a href="httpapi-protocol-bindings-cloudevents.html">Cloud Events HTTP protocol binding</a></li>
<li><a href="httpapi-sse.html">Server sent events</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Connectivity API</a>
<ul>
<li><a href="connectivity-overview.html">Overview</a></li>
<li><a href="connectivity-manage-connections.html">Manage connections</a></li>
<li><a href="connectivity-protocol-bindings-amqp091.html">AMQP 0.9.1 protocol binding</a></li>
<li><a href="connectivity-protocol-bindings-amqp10.html">AMQP 1.0 protocol binding</a></li>
<li><a href="connectivity-protocol-bindings-mqtt.html">MQTT 3.1.1 protocol binding</a></li>
<li><a href="connectivity-protocol-bindings-mqtt5.html">MQTT 5 protocol binding</a></li>
<li><a href="connectivity-protocol-bindings-http.html">HTTP 1.1 protocol binding</a></li>
<li><a href="connectivity-protocol-bindings-kafka2.html">Kafka 2.x protocol binding</a></li>
<li><a href="connectivity-mapping.html">Payload mapping</a></li>
<li><a href="connectivity-header-mapping.html">Header mapping</a></li>
<li><a href="connectivity-tls-certificates.html">TLS certificates</a></li>
<li><a href="connectivity-ssh-tunneling.html">SSH tunneling</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Client SDK</a>
<ul>
<li><a href="client-sdk-overview.html">Overview</a></li>
<li><a href="client-sdk-java.html">Java</a></li>
<li><a href="client-sdk-javascript.html">JavaScript</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Ditto Protocol</a>
<ul>
<li><a href="protocol-overview.html">Overview</a></li>
<li><a href="protocol-twinlive.html">Twin/live channel</a></li>
<li><a href="protocol-specification.html">Specification</a></li>
<li><a href="protocol-specification-topic.html">Protocol topic</a></li>
<li><a href="protocol-specification-errors.html">Errors</a></li>
<li><a href="protocol-specification-things.html">Things group</a></li>
<li class="subfolders">
<a href="#"><span></span>→ commands/events</a>
<ul>
<li><a href="protocol-specification-things-create-or-modify.html">Create/Modify</a></li>
<li><a href="protocol-specification-things-merge.html">Merge</a></li>
<li><a href="protocol-specification-things-retrieve.html">Retrieve</a></li>
<li><a href="protocol-specification-things-delete.html">Delete</a></li>
<li><a href="protocol-specification-acks.html">Acknowledgements</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>→ search/messages</a>
<ul>
<li><a href="protocol-specification-things-search.html">Search</a></li>
<li><a href="protocol-specification-things-messages.html">Messages</a></li>
</ul>
</li>
<li><a href="protocol-specification-policies.html">Policies group</a></li>
<li class="subfolders">
<a href="#"><span></span>→ commands/events</a>
<ul>
<li><a href="protocol-specification-policies-create-or-modify.html">Create/Modify</a></li>
<li><a href="protocol-specification-policies-retrieve.html">Retrieve</a></li>
<li><a href="protocol-specification-policies-delete.html">Delete</a></li>
<li><a href="protocol-specification-policies-announcement.html">Announcement</a></li>
</ul>
</li>
<li><a href="protocol-bindings.html">Bindings</a></li>
<li><a href="protocol-examples.html">Examples</a></li>
<li class="subfolders">
<a href="#"><span></span>→ Things examples</a>
<ul>
<li><a href="protocol-examples-creatething.html">Create a Thing</a></li>
<li><a href="protocol-examples-deletething.html">Delete a Thing</a></li>
<li><a href="protocol-examples-modifything.html">Modify a Thing</a></li>
<li><a href="protocol-examples-retrievething.html">Retrieve a Thing</a></li>
<li><a href="protocol-examples-retrievethings.html">Retrieve multiple Things</a></li>
<li><a href="protocol-examples-modifypolicyid.html">Modify the Policy ID of a Thing</a></li>
<li><a href="protocol-examples-createattributes.html">Create Attributes</a></li>
<li><a href="protocol-examples-deleteattributes.html">Delete Attributes</a></li>
<li><a href="protocol-examples-modifyattributes.html">Modify Attributes</a></li>
<li><a href="protocol-examples-retrieveattributes.html">Retrieve Attributes</a></li>
<li><a href="protocol-examples-createattribute.html">Create a single Attribute</a></li>
<li><a href="protocol-examples-deleteattribute.html">Delete a single Attribute</a></li>
<li><a href="protocol-examples-modifyattribute.html">Modify a single Attribute</a></li>
<li><a href="protocol-examples-retrieveattribute.html">Retrieve a single Attribute</a></li>
<li><a href="protocol-examples-createthingdefinition.html">Create a Definition</a></li>
<li><a href="protocol-examples-deletethingdefinition.html">Delete a Definition</a></li>
<li><a href="protocol-examples-modifythingdefinition.html">Modify a Definition</a></li>
<li><a href="protocol-examples-retrievethingdefinition.html">Retrieve a Definition</a></li>
<li><a href="protocol-examples-createfeatures.html">Create Features</a></li>
<li><a href="protocol-examples-deletefeatures.html">Delete Features</a></li>
<li><a href="protocol-examples-modifyfeatures.html">Modify Features</a></li>
<li><a href="protocol-examples-retrievefeatures.html">Retrieve Features</a></li>
<li><a href="protocol-examples-createfeature.html">Create a single Feature</a></li>
<li><a href="protocol-examples-deletefeature.html">Delete a single Feature</a></li>
<li><a href="protocol-examples-modifyfeature.html">Modify a single Feature</a></li>
<li><a href="protocol-examples-retrievefeature.html">Retrieve a single Feature</a></li>
<li><a href="protocol-examples-createdefinition.html">Create Feature Definition</a></li>
<li><a href="protocol-examples-deletedefinition.html">Delete Feature Definition</a></li>
<li><a href="protocol-examples-modifydefinition.html">Modify Feature Definition</a></li>
<li><a href="protocol-examples-retrievedefinition.html">Retrieve Feature Definition</a></li>
<li><a href="protocol-examples-createproperties.html">Create Feature Properties</a></li>
<li><a href="protocol-examples-deleteproperties.html">Delete Feature Properties</a></li>
<li><a href="protocol-examples-modifyproperties.html">Modify Feature Properties</a></li>
<li><a href="protocol-examples-retrieveproperties.html">Retrieve Feature Properties</a></li>
<li><a href="protocol-examples-createproperty.html">Create a single Property</a></li>
<li><a href="protocol-examples-deleteproperty.html">Delete a single Property</a></li>
<li><a href="protocol-examples-modifyproperty.html">Modify a single Property</a></li>
<li><a href="protocol-examples-retrieveproperty.html">Retrieve a single Property</a></li>
<li><a href="protocol-examples-createdesiredproperties.html">Create desired Feature Properties</a></li>
<li><a href="protocol-examples-deletedesiredproperties.html">Delete desired Feature Properties</a></li>
<li><a href="protocol-examples-modifydesiredproperties.html">Modify desired Feature Properties</a></li>
<li><a href="protocol-examples-retrievedesiredproperties.html">Retrieve desired Feature Properties</a></li>
<li><a href="protocol-examples-createdesiredproperty.html">Create a single desired Property</a></li>
<li><a href="protocol-examples-deletedesiredproperty.html">Delete a single desired Property</a></li>
<li><a href="protocol-examples-modifydesiredproperty.html">Modify a single desired Property</a></li>
<li><a href="protocol-examples-retrievedesiredproperty.html">Retrieve a single desired Property</a></li>
<li><a href="protocol-examples-errorresponses.html">Error responses</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>→ Things merge examples</a>
<ul>
<li><a href="protocol-examples-mergething.html">Merge a Thing</a></li>
<li><a href="protocol-examples-mergepolicyid.html">Merge the Policy ID of a Thing</a></li>
<li><a href="protocol-examples-mergeattributes.html">Merge Attributes</a></li>
<li><a href="protocol-examples-mergeattribute.html">Merge a single Attribute</a></li>
<li><a href="protocol-examples-mergethingdefinition.html">Merge a Definition</a></li>
<li><a href="protocol-examples-mergefeatures.html">Merge Features</a></li>
<li><a href="protocol-examples-mergefeature.html">Merge a single Feature</a></li>
<li><a href="protocol-examples-mergefeaturedefinition.html">Merge Feature Definition</a></li>
<li><a href="protocol-examples-mergeproperties.html">Merge Feature Properties</a></li>
<li><a href="protocol-examples-mergeproperty.html">Merge a single Property</a></li>
<li><a href="protocol-examples-mergedesiredproperties.html">Merge desired Feature Properties</a></li>
<li><a href="protocol-examples-mergedesiredproperty.html">Merge a single desired Property</a></li>
<li><a href="protocol-examples-errorresponses.html">Error responses</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>→ Policies examples</a>
<ul>
<li><a href="protocol-examples-policies-createpolicy.html">Create a Policy</a></li>
<li><a href="protocol-examples-policies-deletepolicy.html">Delete a Policy</a></li>
<li><a href="protocol-examples-policies-modifypolicy.html">Modify a Policy</a></li>
<li><a href="protocol-examples-policies-retrievepolicy.html">Retrieve a Policy</a></li>
<li><a href="protocol-examples-policies-modifypolicyentries.html">Modify entries</a></li>
<li><a href="protocol-examples-policies-retrievepolicyentries.html">Retrieve entries</a></li>
<li><a href="protocol-examples-policies-createpolicyentry.html">Create a single entry</a></li>
<li><a href="protocol-examples-policies-deletepolicyentry.html">Delete a single entry</a></li>
<li><a href="protocol-examples-policies-modifypolicyentry.html">Modify a single entry</a></li>
<li><a href="protocol-examples-policies-retrievepolicyentry.html">Retrieve a single entry</a></li>
<li><a href="protocol-examples-policies-modifysubjects.html">Modify subjects</a></li>
<li><a href="protocol-examples-policies-retrievesubjects.html">Retrieve subjects</a></li>
<li><a href="protocol-examples-policies-createsubject.html">Create a single subject</a></li>
<li><a href="protocol-examples-policies-deletesubject.html">Delete a single subject</a></li>
<li><a href="protocol-examples-policies-modifysubject.html">Modify a single subject</a></li>
<li><a href="protocol-examples-policies-retrievesubject.html">Retrieve a single subject</a></li>
<li><a href="protocol-examples-policies-modifyresources.html">Modify resources</a></li>
<li><a href="protocol-examples-policies-retrieveresources.html">Retrieve resources</a></li>
<li><a href="protocol-examples-policies-createresource.html">Create a single resource</a></li>
<li><a href="protocol-examples-policies-deleteresource.html">Delete a single resource</a></li>
<li><a href="protocol-examples-policies-modifyresource.html">Modify a single resource</a></li>
<li><a href="protocol-examples-policies-retrieveresource.html">Retrieve a single resource</a></li>
<li><a href="protocol-examples-policies-errorresponses.html">Error responses</a></li>
<li><a href="protocol-examples-policies-announcement-subjectDeletion.html">Announcement for subject deletion</a></li>
</ul>
</li>
<li><a href="protocol-examples-search.html">→ Search examples</a></li>
</ul>
</li>
<li><a href="sandbox.html">Sandbox</a></li>
<li><a href="presentations.html">Presentations</a></li>
<li><a href="glossary.html">Glossary</a></li>
<li><a href="feedback.html">Feedback</a></li>
<p class="external">
<a href="#" id="collapseAll">Collapse All</a> | <a href="#" id="expandAll">Expand All</a>
</p>
</ul>
<!-- this highlights the active parent class in the sidebar. this is critical so that the parent expands when you're viewing a page. This must appear below the sidebar code above. Otherwise, if placed inside customscripts.js, the script runs before the sidebar code runs and the class never gets inserted.-->
<script>$("li.active").parents('li').toggleClass("active");
</script>
</div>
<!-- Content Column -->
<div class="col-md-9" id="tg-sb-content">
<div class="post-header">
<h1 class="post-title-main">Acknowledgements / Quality of Service</h1>
</div>
<div class="post-content">
<!-- 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>
<p>Acknowledgements are a concept in Ditto used to indicate that a
<a href="#supported-signal-types">supported signal</a> was successfully received or processed by either an
internal Ditto functionality or an external subscriber of that signal.</p>
<p>Acknowledgements can be seen as (potentially multiple) responses to a single signal like for example a twin command.
This means that Ditto collects all the <a href="#requesting-acks">requested acknowledgements</a> until the signal is
successfully processed within a specified timeout interval.</p>
<h2 id="usage-scenario-examples">Usage scenario examples</h2>
<p>Acknowledgements are useful for accomplishing the following example tasks:</p>
<ul>
<li>Postpone a response to an API request (e.g. block an HTTP request) until one or more specific actions were performed
in Ditto (e.g. a modification was successfully persisted).</li>
<li>Postpone a response until an external subscriber connected to Ditto reports that it successfully processed an
<a href="basic-signals-event.html">event</a> which e.g. resulted by a persistence change of Ditto.</li>
<li>Provide a QoS (quality of service) guarantee of “at least once” when processing
messages in an end-to-end manner by e.g. technically acknowledging/settling a processed signal from a message broker
(e.g. <a href="connectivity-protocol-bindings-amqp10.html">AMQP 1.0</a> or <a href="connectivity-protocol-bindings-mqtt.html">MQTT</a>) only
after it was successfully applied to Ditto and potentially also to 3rd parties.</li>
</ul>
<h2 id="supported-signal-types">Supported signal types</h2>
<p>For the following signal types it is possible to define that certain acknowledgements are <em>requested</em>.</p>
<ul>
<li><a href="basic-signals-command.html">Commands</a> <em>modifying the state of a twin</em> (Twin commands),</li>
<li>Live commands,</li>
<li>Live messages.</li>
</ul>
<h2 id="acknowledgement-labels">Acknowledgement labels</h2>
<p>A common (matching) label links acknowledgement requests and their corresponding acknowledgements.
Ditto already uses some labels for its built-in acknowledgement requests.
Those labels may not be used when sending back a custom acknowledgement.</p>
<h3 id="built-in-acknowledgement-labels">Built-in acknowledgement labels</h3>
<p>Ditto provides built-in acknowledgement requests that are automatically fulfilled on certain actions within the Ditto
cluster:</p>
<ul>
<li><strong>twin-persisted</strong>: For acknowledgement requests of twin modifying commands.
It is fulfilled when a modifying command has successfully updated the digital twin in Ditto’s persistence.
It is ignored for commands in the live channel.</li>
<li><strong>live-response</strong>: For acknowledgement requests of live commands and live messages.
It is fulfilled when a subscriber of the live command or message sends a corresponding response.
It is ignored for commands in the twin channel.</li>
<li><strong>search-persisted</strong>: For acknowledgement requests of twin modifying commands.
It is fulfilled when a modifying command has successfully updated the search index of the digital twin.
It is ignored for commands in the live channel.</li>
</ul>
<h3 id="custom-acknowledgement-labels">Custom acknowledgement labels</h3>
<p>In addition to the <a href="#built-in-acknowledgement-labels">built-in</a> acknowledgement requests,
a supported signal can contain custom acknowledgement requests.
A subscriber of such a signal can detect a requested acknowledgement via the <code class="highlighter-rouge">"requested-acks"</code> header.
If the subscriber is in charge of handling a requested acknowledgement it
<a href="#issuing-acknowledgements">issues an acknowledgement</a>.</p>
<h2 id="acknowledgements-acks">Acknowledgements (ACKs)</h2>
<p>A single acknowledgement contains the following information:</p>
<ul>
<li>Acknowledgement label (one of the requested labels of the <a href="#requesting-acks">ack requests</a>)</li>
<li>Header fields
<ul>
<li>mandatory: <strong>correlation-id</strong> the same correlation ID as the one of the signal which requested the acknowledgement</li>
<li>optional: additional header fields</li>
</ul>
</li>
<li>Status code (HTTP status code semantic) defining whether an acknowledgement was successful or not</li>
<li>Optional payload as JSON</li>
</ul>
<p>The <a href="protocol-specification-acks.html">Ditto Protocol specification</a> describes in detail what is contained.<br />
An example of how acknowledgements in Ditto Protocol look like can be found at the
<a href="protocol-examples.html#acknowledgements-acks">acknowledgement examples</a> section.</p>
<h2 id="requesting-acks">Requesting ACKs</h2>
<p>With every supported signal there is the option to request acknowledgements.<br />
Acknowledgement requests are expressed as protocol specific header fields of signals.
The following sections explain the various ways of requesting acknowledgements.</p>
<p><a href="basic-signals-event.html">Events</a> emitted by Ditto will include the custom acknowledgement requests in the
<code class="highlighter-rouge">"requested-acks"</code> header.</p>
<h3 id="requesting-acks-via-http">Requesting ACKs via HTTP</h3>
<p>Either specify the following HTTP header fields:</p>
<ul>
<li><strong>requested-acks</strong>: a comma separated list of <a href="#acknowledgement-labels">acknowledgement labels</a>.<br />
Example: <code class="highlighter-rouge">requested-acks: twin-persisted,some-connection-id:my-custom-ack</code>.</li>
<li><strong>timeout</strong>: an optional time interval (in ms, s or m) to define how long the HTTP request should wait for
acknowledgements and block.
Default and maximum value: <code class="highlighter-rouge">60s</code>.<br />
Examples: <code class="highlighter-rouge">timeout: 42s</code>, <code class="highlighter-rouge">timeout: 250ms</code>, <code class="highlighter-rouge">timeout: 1m</code>.</li>
</ul>
<p>Or specify the header fields as query parameters to the HTTP params, e.g.:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PUT /api/2/things/org.eclipse.ditto:thing-1?requested-acks=twin-persisted,my-custom-ack&amp;timeout=42s
</code></pre></div></div>
<p>The response of an HTTP request, which requested several acknowledgements, will differ from the response to an HTTP
request without acknowledgement requests.</p>
<p>Example response when 2 acknowledgements were requested and were successful. The overall HTTP status code will be
<code class="highlighter-rouge">200</code> (OK) in this case:</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">"twin-persisted"</span><span class="p">:</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">201</span><span class="p">,</span><span class="w">
</span><span class="s2">"payload"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"thingId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto:thing-1"</span><span class="p">,</span><span class="w">
</span><span class="s2">"policyId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto:thing-1"</span><span class="w">
</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">"correlation-id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"db878735-4957-4fd9-92dc-6f09bb12a093"</span><span class="p">,</span><span class="w">
</span><span class="s2">"version"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w">
</span><span class="s2">"etag"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\"</span><span class="s2">rev:1</span><span class="se">\"</span><span class="s2">"</span><span class="p">,</span><span class="w">
</span><span class="s2">"location"</span><span class="p">:</span><span class="w"> </span><span class="s2">"http://127.0.0.1:8080/api/2/things/org.eclipse.ditto:thing-1"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"my-custom-ack"</span><span class="p">:</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">200</span><span class="p">,</span><span class="w">
</span><span class="s2">"payload"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"outcome"</span><span class="p">:</span><span class="w"> </span><span class="s2">"green"</span><span class="w">
</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">"version"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w">
</span><span class="s2">"correlation-id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"db878735-4957-4fd9-92dc-6f09bb12a093"</span><span class="w">
</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></code></pre></div></div>
<p>Example response when 2 acknowledgements were requested and one lead to a timeout. The overall HTTP status code will be
<code class="highlighter-rouge">424</code> (Dependency failed) in this case:</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">"twin-persisted"</span><span class="p">:</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">201</span><span class="p">,</span><span class="w">
</span><span class="s2">"payload"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"thingId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto:thing-1"</span><span class="p">,</span><span class="w">
</span><span class="s2">"policyId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto:thing-1"</span><span class="w">
</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">"correlation-id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"db878735-4957-4fd9-92dc-6f09bb12a093"</span><span class="p">,</span><span class="w">
</span><span class="s2">"version"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w">
</span><span class="s2">"etag"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\"</span><span class="s2">rev:1</span><span class="se">\"</span><span class="s2">"</span><span class="p">,</span><span class="w">
</span><span class="s2">"location"</span><span class="p">:</span><span class="w"> </span><span class="s2">"http://127.0.0.1:8080/api/2/things/org.eclipse.ditto:thing-1"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"my-custom-ack"</span><span class="p">:</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">408</span><span class="p">,</span><span class="w">
</span><span class="s2">"payload"</span><span class="p">:</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">408</span><span class="p">,</span><span class="w">
</span><span class="s2">"error"</span><span class="p">:</span><span class="w"> </span><span class="s2">"acknowledgement:request.timeout"</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">"The acknowledgement request reached the specified timeout of 42,000ms."</span><span class="p">,</span><span class="w">
</span><span class="s2">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Try increasing the timeout and make sure that the requested acknowledgement is sent back in time."</span><span class="w">
</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">"version"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w">
</span><span class="s2">"correlation-id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"db878735-4957-4fd9-92dc-6f09bb12a093"</span><span class="w">
</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></code></pre></div></div>
<h3 id="requesting-acks-via-websocket">Requesting ACKs via WebSocket</h3>
<p>Together with a received Ditto <a href="basic-signals-command.html">command</a> in <a href="protocol-specification.html">Ditto Protocol</a>,
<code class="highlighter-rouge">"requested-acks"</code> (as JsonArray of strings) and <code class="highlighter-rouge">"timeout"</code> headers in the
<a href="protocol-specification.html#headers">Ditto Protocol headers</a> can be included in order to request acknowledgements via
WebSocket.</p>
<p>The response will be an (aggregating) <a href="protocol-specification-acks.html#acknowledgements-aggregating">acknowledgements</a>
message.</p>
<h3 id="requesting-acks-via-connections">Requesting ACKs via connections</h3>
<p>Acknowledgements for Ditto managed <a href="basic-connections.html#sources">connection sources</a> can be requested in 2 ways:</p>
<ul>
<li>specifically for each consumed supported signal as part of
the <a href="protocol-specification.html#headers">Ditto Protocol headers</a> <code class="highlighter-rouge">"requested-acks"</code> (as JsonArray of strings)</li>
<li>by configuring the managed connection source to
<a href="basic-connections.html#source-acknowledgement-requests">request acknowledgements for all consumed supported signals</a>.</li>
</ul>
<h4 id="requesting-acks-via-ditto-protocol-message">Requesting ACKs via Ditto Protocol message</h4>
<p>Together with a received Ditto <a href="basic-signals-command.html">command</a> in <a href="protocol-specification.html">Ditto Protocol</a>,
<code class="highlighter-rouge">"requested-acks"</code> (as JsonArray of strings) and <code class="highlighter-rouge">"timeout"</code> headers in the
<a href="protocol-specification.html#headers">Ditto Protocol headers</a> can be included in order to request acknowledgements
via established connections consuming messages from <a href="basic-connections.html#sources">sources</a>.</p>
<p>The response will be an (aggregating) <a href="protocol-specification-acks.html#acknowledgements-aggregating">acknowledgements</a>
message.</p>
<h4 id="requesting-acks-via-connection-source-configuration">Requesting ACKs via connection source configuration</h4>
<p><a href="basic-connections.html#sources">Connection sources</a> can be
<a href="basic-connections.html#source-acknowledgement-requests">configured to add specific acknowledgement requests</a> for each
consumed message of the underlying physical connection (e.g. to a message broker).</p>
<p>This can be used in order to ensure that e.g. all messages consumed from a single source should be processed in an
“at least once” mode (QoS 1).
E.g. if configured that the <a href="#built-in-acknowledgement-labels">built-in</a> <code class="highlighter-rouge">twin-persisted</code> acknowledgement is requested,
a received twin-modifying command will only be technically acknowledged to the connection channel if Ditto successfully
applied and persisted the command.</p>
<div class="alert alert-info" role="alert"><i class="fa fa-info-circle"></i> <b>Note:</b> These requested acknowledgements will be appended after payload mapping is applied.<br />
This means, that in case you decided to split your message into multiple messages, all of these messages will request the same acknowledgements.<br />
If this is not what you want to achieve, have a look at <a href="#requesting-acks-via-ditto-protocol-message-in-payload-mapping">how to add acknowledgement requests during payload mapping</a>.</div>
<h4 id="requesting-acks-via-ditto-protocol-message-in-payload-mapping">Requesting ACKs via Ditto Protocol message in payload mapping</h4>
<p>During inbound payload mapping, you can create one or more Ditto Protocol messages.</p>
<p>If you configured your connection source to add requested acknowledgements to your commands, this will cause all
produced messages to request the same acknowledgements.<br />
If you however want to add requested acknowledgements only to some of those created messages, you need to set the
<code class="highlighter-rouge">"requested-acks"</code> header (as described in
<a href="#requesting-acks-via-ditto-protocol-message">Requesting ACKs via Ditto Protocol message</a> section) during payload
mapping for those commands you like to request an acknowledgement.</p>
<h2 id="issuing-acknowledgements">Issuing acknowledgements</h2>
<p>Acknowledgements are issued by subscribers of events generated by twin-modifying commands, or by subscribers of
live commands and live messages. In order to issue a single acknowledgement, a
<a href="protocol-specification-acks.html#acknowledgement">Ditto Protocol acknowledgement</a> message has to be built and sent
back, using the same <code class="highlighter-rouge">"correlation-id"</code> in the <a href="protocol-specification.html#headers">protocol headers</a> as contained
in the received twin event, live command or live message.</p>
<p>The labels of issued acknowledgements are globally unique for each subscriber. Before a subscriber is allowed to
send acknowledgements, it must declare the labels of acknowledgements it sends. Any declared label taken by another
subscriber causes an appropriate error for each channel that may issue acknowledgements.</p>
<h3 id="issuing-acks-via-http">Issuing ACKs via HTTP</h3>
<p>It is not possible to issue acknowledgements via HTTP, because it is impossible to subscribe for twin events,
live commands or live messages via HTTP.</p>
<h3 id="issuing-acks-via-websocket">Issuing ACKs via WebSocket</h3>
<p>Create and send the <a href="protocol-specification-acks.html#acknowledgement">Ditto Protocol acknowledgement</a> message over an
established WebSocket in response to a twin event, live command or live message that contains a <code class="highlighter-rouge">"requested-acks"</code>
header.</p>
<p>Only acknowledgements with declared labels are accepted. To declare acknowledgement labels, set them as the value
of the query parameter <code class="highlighter-rouge">declared-acks</code> as comma-separated list:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>GET /ws/2?declared-acks=some-connection-id:ack-label-1,my:ack-label-2
</code></pre></div></div>
<p>The websocket will be closed right after it has been opened if any other another subscriber already declared the same label.<br />
This means that it is not possible to establish a second websocket connection with the same declared acknowledgements
before closing the first one.</p>
<div class="alert alert-danger" role="alert"><i class="fa fa-exclamation-circle"></i> <b>Warning:</b> Therefore, it is not recommended relying on the websocket API for high
availability scenarios.</div>
<h3 id="issuing-acks-via-connections">Issuing ACKs via connections</h3>
<p>Requested acknowledgements for Ditto managed <a href="basic-connections.html#targets">connection targets</a> can be issued in 2
ways:</p>
<ul>
<li>specifically for each published twin event, live command or live message by sending a
<a href="protocol-specification-acks.html#acknowledgement">Ditto Protocol acknowledgement</a> back,
via a source of the same connection;</li>
<li>by configuring the managed connection target to automatically
<a href="basic-connections.html#target-issued-acknowledgement-label">issue acknowledgements</a> for all published twin events,
live commands and live messages that request them.</li>
</ul>
<p>Acknowledgements sent via a source must
<a href="basic-connections.html#source-declared-acknowledgement-labels">have their labels declared</a>
in the field <code class="highlighter-rouge">declaredAcks</code> as a JSON array.<br />
The labels of target-issued acknowledgements are declared automatically.<br />
Acknowledgement labels of a connection must be prefixed by the connection ID or the <code class="highlighter-rouge">{{connection:id}}</code>
placeholder followed by a colon, for example <code class="highlighter-rouge">{{connection:id}}:my-custom-ack</code>.</p>
<p>If some source-declared or target-issued acknowledgement labels are taken by a websocket subscriber,
all acknowledgements sent by the connection are rejected with error until the websocket is closed.</p>
<h4 id="issuing-acks-via-ditto-protocol-acknowledgement-message">Issuing ACKs via Ditto Protocol acknowledgement message</h4>
<p>Create and send the <a href="protocol-specification-acks.html#acknowledgement">Ditto Protocol acknowledgement</a> message over a<br />
source of the connection, in response to an event, live command or live message which contained an <code class="highlighter-rouge">"requested-acks"</code>
header.</p>
<h4 id="issuing-acks-via-connection-target-configuration">Issuing ACKs via connection target configuration</h4>
<p><a href="basic-connections.html#targets">Connection targets</a> can be configured to
<a href="basic-connections.html#target-issued-acknowledgement-label">issue certain acknowledgements automatically</a>
for each twin event, live command or live message published to the underlying physical connection (e.g. to a message
broker).</p>
<p>This can be used in order to automatically issue technical acknowledgements once an event, live command or live message
was published to an HTTP endpoint or into a message broker. When this target guarantees having processed the event
via its protocol (for HTTP for example when a status code <code class="highlighter-rouge">2xx</code> is returned), a successful acknowledgement is created
and returned to the requester.</p>
<h2 id="quality-of-service">Quality of Service</h2>
<h3 id="qos-0---at-most-once">QoS 0 - at most once</h3>
<p>By default, Ditto processes all messages/commands processed in an “at most once” (or QoS 0) semantic.
For many of the use cases in the IoT, QoS 0 is sufficient, e.g. when processing telemetry data of a sensor:
if one sensor value is not applied to the digital twin there will soon follow the next sensor reading, and the twin will
be eventually up to date again.</p>
<h3 id="qos-1---at-least-once">QoS 1 - at least once</h3>
<p>However, there are IoT use cases where it is of upmost importance that a signal is processed “at least once” (or QoS 1),
e.g. in order to guarantee that it was persisted in the digital twin or that an <a href="basic-signals-event.html">event</a>
consumer connected to Ditto did successfully receive a <a href="basic-changenotifications.html">notification</a> which resulted
from a <a href="basic-signals-command.html">command</a> which Ditto received and processed.</p>
<p>The “acknowledgements” concept documented on this page provides means by which supported signals Ditto consumes and
processes are treated with an “at least once” (or QoS 1) semantic.</p>
<p><a href="protocol-specification-things-create-or-modify.html">Create/modify commands</a> will technically be acknowledged on the
sent channel (e.g. HTTP or WebSocket or any <a href="basic-connections.html#connection-types">connection type</a>) when it was a
success.<br />
If it could not be applied successfully, the signal will be negatively acknowledged.
The <a href="protocol-specification-acks.html#combined-status-code">status code of the acknowledgement</a> reflects the failure.</p>
<p>Based on the used channel, the acknowledgement will be translated to the capabilities of the command or live message
channel, e.g. for HTTP an HTTP response will be sent with the outcome as HTTP status (<code class="highlighter-rouge">2xx</code> for a successful
acknowledgement, and <code class="highlighter-rouge">4xx</code> for a non-successful one) together with additional details as HTTP response.</p>
<h3 id="assure-qos-until-persisted-in-ditto---twin-persisted">Assure QoS until persisted in Ditto - twin-persisted</h3>
<p>In order to ensure that a <a href="protocol-specification-things-create-or-modify.html">create/modify command</a> resulted in a
successful update of twin in Ditto’s managed database, <a href="#requesting-acks">request the acknowledgement</a> for
the <a href="#built-in-acknowledgement-labels">built-in “twin-persisted”</a> acknowledgement label.</p>
<h3 id="assure-qos-until-processing-of-a-live-commandmessage-by-a-subscriber---live-response">Assure QoS until processing of a live command/message by a subscriber - live-response</h3>
<p>In order to ensure that a live command or live message is processed by a subscriber, set <code class="highlighter-rouge">response-required</code> to true.
This way the <a href="#built-in-acknowledgement-labels">built-in “live-response” acknowledgement label</a> is <a href="#requesting-acks">automatically requested</a> for the live command/message.
This acknowledgement request is fulfilled when the subscriber sends a live response or message response.</p>
<h3 id="assure-qos-until-processing-of-a-twin-event-or-live-commandmessage-by-subscribers---custom-label">Assure QoS until processing of a twin event or live command/message by subscribers - custom label</h3>
<p>In order to ensure that a <a href="protocol-specification-things-create-or-modify.html">create/modify command</a> resulted in an
event which was consumed by an application integrating with Ditto, or that a live command or live message is consumed
without any live or message response, <a href="#requesting-acks">request the acknowledgement</a> for a
<a href="#custom-acknowledgement-labels">custom acknowledgement label</a>.</p>
<h2 id="weak-acknowledgements-wacks">Weak Acknowledgements (WACKs)</h2>
<p>Since there are scenarios where the subscriber of events or live messages has defined an RQL filter or is not allowed to receive an event by a policy, it is not always possible that an acknowledgement can be provided.
To avoid that a command fails because of a missing acknowledgement for those reasons, we introduced weak acknowledgements.</p>
<p>These weak acknowledgements are issued automatically by ditto, in case a message or an event is filtered by a subscriber which declared to provide one or more of the requested acknowledgements for the command.
A weak acknowledgement can be identified by checking the header with value <code class="highlighter-rouge">ditto-weak-ack</code>.
Weak acknowledgements have this header set to <code class="highlighter-rouge">true</code>.</p>
<p>These weak acknowledgements do not cause redelivery of messages consumed by a Connection.</p>
<h2 id="interaction-between-headers">Interaction between headers</h2>
<p>Three headers control how Ditto responds to a command: <code class="highlighter-rouge">response-required</code>, <code class="highlighter-rouge">requested-acks</code>, <code class="highlighter-rouge">timeout</code>.</p>
<ul>
<li><code class="highlighter-rouge">response-required</code>: <code class="highlighter-rouge">true</code> or <code class="highlighter-rouge">false</code>.<br />
It governs whether the user gets a (detailed) reply.<br />
In case of a live message or a live command it also has impact on the <code class="highlighter-rouge">requested-acks</code>:
<ul>
<li>If <code class="highlighter-rouge">response-required</code> is <code class="highlighter-rouge">true</code>, the acknowledgement label <code class="highlighter-rouge">live-response</code> will be added to <code class="highlighter-rouge">requested-acks</code> if not
present and <code class="highlighter-rouge">requested-acks</code> was not explicitly set to an empty JSON array.<br /></li>
<li>If it is <code class="highlighter-rouge">false</code>, the acknowledgement label <code class="highlighter-rouge">live-response</code> will be removed from <code class="highlighter-rouge">requested-acks</code> if present.</li>
</ul>
</li>
<li><code class="highlighter-rouge">requested-acks</code>: JSON array of acknowledgement requests.<br />
It determines the content of the response and transport-layer message settlement.</li>
<li><code class="highlighter-rouge">timeout</code>: Duration.<br />
It governs how long Ditto waits for responses and acknowledgements.</li>
</ul>
<p>It is considered a client error if <code class="highlighter-rouge">timeout</code> is set to <code class="highlighter-rouge">0s</code> while <code class="highlighter-rouge">response-required</code> is <code class="highlighter-rouge">true</code> or <code class="highlighter-rouge">requested-acks</code> is
nonempty.</p>
<h3 id="default-header-values">Default header values</h3>
<p>Ditto set each of the three headers <code class="highlighter-rouge">response-required</code>, <code class="highlighter-rouge">requested-acks</code>, <code class="highlighter-rouge">timeout</code> to a default value according to any
values of the other two headers set by the user.
The default values depend only on headers set by the user; they do not depend on each other.
Setting the default header values this way never produces any combination considered a client error unless the headers
set by the user already cause a client error.</p>
<table>
<thead>
<tr>
<th>Header</th>
<th>Default value</th>
<th>Default value if all three headers are not set</th>
</tr>
</thead>
<tbody>
<tr>
<td>response-required</td>
<td><code class="highlighter-rouge">false</code> if <code class="highlighter-rouge">timeout</code> is zero or <code class="highlighter-rouge">requested-acks</code> is empty, <code class="highlighter-rouge">true</code> otherwise</td>
<td><code class="highlighter-rouge">true</code></td>
</tr>
<tr>
<td>requested-acks</td>
<td><code class="highlighter-rouge">empty</code> if <code class="highlighter-rouge">timeout</code> is zero or <code class="highlighter-rouge">response-required</code> is <code class="highlighter-rouge">false</code>, the channel’s default acknowledgement request otherwise</td>
<td><code class="highlighter-rouge">["twin-persisted"]</code> for TWIN channel,<br /><code class="highlighter-rouge">["live-response"]</code> for LIVE channel</td>
</tr>
<tr>
<td>timeout</td>
<td><code class="highlighter-rouge">60s</code></td>
<td><code class="highlighter-rouge">60s</code></td>
</tr>
</tbody>
</table>
<p>The following sections show how each Ditto API interprets the three headers.</p>
<h3 id="http">HTTP</h3>
<p>Since an HTTP response always follows an HTTP request, the header <code class="highlighter-rouge">response-required</code> is interpreted as whether
the user wants a <em>detailed</em> response.
If it is set to <code class="highlighter-rouge">false</code>, the HTTP response consists of status line and headers without body, or with a minimal body
containing other status codes.
If acknowledgements are requested, the HTTP response is delayed until all requested acknowledgements are received.
Generally, if a request cannot be answered within the defined timeout, the HTTP response has status code 408.
A response containing successful acknowledgements (2xx) and at least one failed acknowledgement (4xx) has status code
424 (failed dependency).
In this case the status codes of all acknowledgements should be check to determine the one which caused the failure.</p>
<table>
<thead>
<tr>
<th>API</th>
<th>response-required</th>
<th>requested-acks</th>
<th>timeout</th>
<th>Outcome</th>
</tr>
</thead>
<tbody>
<tr>
<td>HTTP</td>
<td>false</td>
<td>empty</td>
<td>zero</td>
<td>202 Accepted immediately</td>
</tr>
<tr>
<td>HTTP</td>
<td>false</td>
<td>empty</td>
<td>non-zero</td>
<td>202 Accepted immediately</td>
</tr>
<tr>
<td>HTTP</td>
<td>false</td>
<td>non-empty</td>
<td>zero</td>
<td>400 Bad Request: timeout may not be zero if acknowledgements are requested</td>
</tr>
<tr>
<td>HTTP</td>
<td>false</td>
<td>non-empty</td>
<td>non-zero</td>
<td>202 Accepted after receiving the requested acknowledgements</td>
</tr>
<tr>
<td>HTTP</td>
<td>true</td>
<td>empty</td>
<td>zero</td>
<td>400 Bad Request: timeout may not be zero if response is required</td>
</tr>
<tr>
<td>HTTP</td>
<td>true</td>
<td>empty</td>
<td>non-zero</td>
<td>Response</td>
</tr>
<tr>
<td>HTTP</td>
<td>true</td>
<td>non-empty</td>
<td>zero</td>
<td>400 Bad Request: timeout may not be zero if response is required</td>
</tr>
<tr>
<td>HTTP</td>
<td>true</td>
<td>non-empty</td>
<td>non-zero</td>
<td>Aggregated response and acknowledgements</td>
</tr>
</tbody>
</table>
<h3 id="websocket">WebSocket</h3>
<p>In the absence of client errors, a response is sent for a command if and only if <code class="highlighter-rouge">response-required</code> is set to <code class="highlighter-rouge">true</code>.
Ditto supports no transport-layer message settlement for WebSocket; acknowledgements are only received as text frames.
Consequently, it is considered a client error to have non-empty <code class="highlighter-rouge">requested-acks</code> while <code class="highlighter-rouge">response-required</code> is set to
<code class="highlighter-rouge">false</code>.</p>
<table>
<thead>
<tr>
<th>API</th>
<th>response-required</th>
<th>requested-acks</th>
<th>timeout</th>
<th>Outcome</th>
</tr>
</thead>
<tbody>
<tr>
<td>WebSocket</td>
<td>false</td>
<td>empty</td>
<td>zero</td>
<td>No response</td>
</tr>
<tr>
<td>WebSocket</td>
<td>false</td>
<td>empty</td>
<td>non-zero</td>
<td>No response</td>
</tr>
<tr>
<td>WebSocket</td>
<td>false</td>
<td>non-empty</td>
<td>zero</td>
<td>Error: timeout may not be zero if acknowledgements are requested</td>
</tr>
<tr>
<td>WebSocket</td>
<td>false</td>
<td>non-empty</td>
<td>non-zero</td>
<td>Error: WebSocket cannot send acknowledgements without a response</td>
</tr>
<tr>
<td>WebSocket</td>
<td>true</td>
<td>empty</td>
<td>zero</td>
<td>Error: timeout may not be zero if response is required</td>
</tr>
<tr>
<td>WebSocket</td>
<td>true</td>
<td>empty</td>
<td>non-zero</td>
<td>Response</td>
</tr>
<tr>
<td>WebSocket</td>
<td>true</td>
<td>non-empty</td>
<td>zero</td>
<td>Error: timeout may not be zero if response is required</td>
</tr>
<tr>
<td>WebSocket</td>
<td>true</td>
<td>non-empty</td>
<td>non-zero</td>
<td>Aggregated response and acknowledgements</td>
</tr>
</tbody>
</table>
<h3 id="connectivity">Connectivity</h3>
<p>For any incoming supported signal through a connection source, the header <code class="highlighter-rouge">response-required</code> determines whether a
response message is published at the reply-target of the source.
The header <code class="highlighter-rouge">requested-acks</code> determines the transport-layer message settlement and the content of any response message
published at the reply-target.
Examples of transport-layer message settlement mechanisms are AMQP 0.9.1 consumer acknowledgement mode, AMQP 1.0
disposition frames, and MQTT PUBACK/PUBREC/PUBREL messages for incoming PUBLISH with QoS 1 or 2.</p>
<table>
<thead>
<tr>
<th>API</th>
<th>response-required</th>
<th>requested-acks</th>
<th>timeout</th>
<th>Outcome</th>
</tr>
</thead>
<tbody>
<tr>
<td>Connectivity</td>
<td>false</td>
<td>empty</td>
<td>zero</td>
<td>Nothing published at reply-target;<br />message settled immediately</td>
</tr>
<tr>
<td>Connectivity</td>
<td>false</td>
<td>empty</td>
<td>non-zero</td>
<td>Nothing published at reply-target;<br />message settled immediately</td>
</tr>
<tr>
<td>Connectivity</td>
<td>false</td>
<td>non-empty</td>
<td>zero</td>
<td>Error published at reply-target: timeout may not be zero if acknowledgements are requested;<br />message settled negatively</td>
</tr>
<tr>
<td>Connectivity</td>
<td>false</td>
<td>non-empty</td>
<td>non-zero</td>
<td>Nothing published at reply-target;<br />message settled after receiving the requested acknowledgements</td>
</tr>
<tr>
<td>Connectivity</td>
<td>true</td>
<td>empty</td>
<td>zero</td>
<td>Error published at reply-target: timeout may not be zero when response is required;<br />message settled negatively</td>
</tr>
<tr>
<td>Connectivity</td>
<td>true</td>
<td>empty</td>
<td>non-zero</td>
<td>Response published at reply-target;<br />message settled immediately</td>
</tr>
<tr>
<td>Connectivity</td>
<td>true</td>
<td>non-empty</td>
<td>zero</td>
<td>Error published at reply-target: timeout may not be zero if response is required;<br />message settled negatively</td>
</tr>
<tr>
<td>Connectivity</td>
<td>true</td>
<td>non-empty</td>
<td>non-zero</td>
<td>Aggregated response and acknowledgements published at reply-target;<br />message settled after receiving the requested acknowledgements</td>
</tr>
</tbody>
</table>
<h3 id="default-header-values-1">Default header values</h3>
<p>Ditto set each of the three headers <code class="highlighter-rouge">response-required</code>, <code class="highlighter-rouge">requested-acks</code>, <code class="highlighter-rouge">timeout</code> to a default value according to any
values of the other two headers set by the user.
The default values depend only on headers set by the user; they do not depend on each other.
Setting the default header values this way never produces any combination considered a client error unless the headers
set by the user already cause a client error.</p>
<table>
<thead>
<tr>
<th>Header</th>
<th>Default value</th>
<th>Default value if all three headers are not set</th>
</tr>
</thead>
<tbody>
<tr>
<td>response-required</td>
<td><code class="highlighter-rouge">false</code> if <code class="highlighter-rouge">timeout</code> is zero, <code class="highlighter-rouge">true</code> otherwise</td>
<td><code class="highlighter-rouge">true</code></td>
</tr>
<tr>
<td>requested-acks</td>
<td><code class="highlighter-rouge">empty</code> if <code class="highlighter-rouge">timeout</code> is zero or <code class="highlighter-rouge">response-required</code> is <code class="highlighter-rouge">false</code>, the channel’s default acknowledgement request otherwise</td>
<td><code class="highlighter-rouge">["twin-persisted"]</code> for TWIN channel,<br /><code class="highlighter-rouge">["live-response"]</code> for LIVE channel</td>
</tr>
<tr>
<td>timeout</td>
<td><code class="highlighter-rouge">60s</code></td>
<td><code class="highlighter-rouge">60s</code></td>
</tr>
</tbody>
</table>
<div class="tags">
<b>Tags: </b>
<a href="tag_model.html" class="btn btn-default navbar-btn cursorNorm" role="button">model</a>
</div>
</div>
<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">
&copy;2021 Eclipse Ditto™.
Site last generated: May 20, 2021 <br />
</p>
<div class="quickLinks">
<a href="https://www.eclipse.org/legal/privacy.php" target="_blank">
&gt; Privacy Policy
</a>
<a href="https://www.eclipse.org/legal/termsofuse.php" target="_blank">
&gt; Terms of Use
</a>
<a href="https://www.eclipse.org/legal/copyright.php" target="_blank">
&gt; Copyright Agent
</a>
<a href="https://www.eclipse.org/legal" target="_blank">
&gt; Legal
</a>
<a href="https://www.eclipse.org/legal/epl-2.0/" target="_blank">
&gt; License
</a>
<a href="https://eclipse.org/security" target="_blank">
&gt; Report a Vulnerability
</a>
</div>
</div>
</div>
</footer>
</div>
<!-- /.row -->
</div>
<!-- /.container -->
</div>
<!-- /#main -->
</div>
</body>
</html>