| <!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="protocolconnectivity, binding, protocol, mqtt, mqtt5"> |
| <title> MQTT 5 protocol binding • 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"> <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="MQTT 5 protocol binding">{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><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 class="active"><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> |
| |
| |
| |
| |
| |
| |
| <li><a href="connectivity-hmac-signing.html">HMAC signing</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/announcements</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-specification-connections.html">Connections group</a></li> |
| |
| |
| |
| <li class="subfolders"> |
| <a href="#"><span></span>→ announcements</a> |
| <ul> |
| |
| |
| |
| <li><a href="protocol-specification-connections-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 class="subfolders"> |
| <a href="#"><span></span>→ Connections examples</a> |
| <ul> |
| |
| |
| |
| <li><a href="protocol-examples-connections-announcement-opened.html">Announcement for connection opened</a></li> |
| |
| |
| |
| |
| |
| <li><a href="protocol-examples-connections-announcement-closed.html">Announcement for connection gracefully closed</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">MQTT 5 protocol binding</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>Consume messages from MQTT 5 brokers via <a href="#source-format">sources</a> and send messages to MQTT 5 brokers via |
| <a href="#target-format">targets</a>.</p> |
| |
| <h2 id="content-type">Content-type</h2> |
| |
| <p>When MQTT messages are sent in <a href="protocol-overview.html">Ditto Protocol</a>, |
| the payload should be <code class="highlighter-rouge">UTF-8</code> encoded strings.</p> |
| |
| <p>If messages, which are not in Ditto Protocol, should be processed, a <a href="connectivity-mapping.html">payload mapping</a> must |
| be configured for the connection in order to transform the messages.</p> |
| |
| <h2 id="mqtt-5-properties">MQTT 5 properties</h2> |
| |
| <p>Supported MQTT 5 properties, which are interpreted in a specific way are:</p> |
| |
| <ul> |
| <li><code class="highlighter-rouge">9 (0x09) Correlation Data</code>: For correlating request messages and events. Twin events have the correlation IDs of |
| <a href="protocol-twinlive.html#twin">Twin commands</a> that produced them. Stored in the ditto protocol header <code class="highlighter-rouge">correlation-id</code>.</li> |
| <li><code class="highlighter-rouge">8 (0x08) Response Topic</code>: The MQTT topic a requests response is expected in. |
| If a command sets the header <code class="highlighter-rouge">reply-to</code>, then its response is published at the topic equal to the header value.</li> |
| <li><code class="highlighter-rouge">3 (0x03) Content Type</code>: The UTF-8 encoded string representation of the payloads content MIME type.</li> |
| </ul> |
| |
| <h2 id="specific-connection-configuration">Specific connection configuration</h2> |
| |
| <p>The common configuration for connections in <a href="basic-connections.html#sources">Connections > Sources</a> and |
| <a href="basic-connections.html#targets">Connections > Targets</a> applies here as well.</p> |
| |
| <p>Following are some specifics for MQTT connections:</p> |
| |
| <h3 id="source-format">Source format</h3> |
| |
| <p>For an MQTT connection:</p> |
| |
| <ul> |
| <li>Source <code class="highlighter-rouge">"addresses"</code> are MQTT topics to subscribe to. Wildcards <code class="highlighter-rouge">+</code> and <code class="highlighter-rouge">#</code> are allowed.</li> |
| <li><code class="highlighter-rouge">"authorizationContext"</code> array that contains the authorization subjects in whose context |
| inbound messages are processed. These subjects may contain placeholders, see |
| <a href="basic-connections.html#placeholder-for-source-authorization-subjects">placeholders</a> section for more information.</li> |
| <li>The required field <code class="highlighter-rouge">"qos"</code> sets the maximum Quality of Service to request when subscribing for messages. Its value |
| can be <code class="highlighter-rouge">0</code> for at-most-once delivery, <code class="highlighter-rouge">1</code> for at-least-once delivery and <code class="highlighter-rouge">2</code> for exactly-once delivery. |
| Support of any Quality of Service depends on the external MQTT broker</li> |
| </ul> |
| |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> |
| </span><span class="s2">"addresses"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> |
| </span><span class="s2">"<mqtt_topic>"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"..."</span><span class="w"> |
| </span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"authorizationContext"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"ditto:inbound-auth-subject"</span><span class="p">,</span><span class="w"> </span><span class="s2">"..."</span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"qos"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> |
| </span><span class="p">}</span><span class="w"> |
| </span></code></pre></div></div> |
| |
| <h4 id="source-header-mapping">Source header mapping</h4> |
| |
| <p>MQTT 5 supports so-called user defined properties, which are defined for every message type. |
| In addition, Ditto extracts the following headers from each consumed message:</p> |
| |
| <ul> |
| <li><code class="highlighter-rouge">mqtt.topic</code>: contains the MQTT topic on which a message was received</li> |
| <li><code class="highlighter-rouge">mqtt.qos</code>: contains the MQTT QoS value of a received message</li> |
| <li><code class="highlighter-rouge">mqtt.retain</code>: contains the MQTT retain flag of a received message</li> |
| <li><code class="highlighter-rouge">correlation-id</code>: contains the MQTT 5 “correlation data” value</li> |
| <li><code class="highlighter-rouge">reply-to</code>: contains the MQTT 5 “response topic” value</li> |
| <li><code class="highlighter-rouge">content-type</code>: contains the MQTT 5 “content type” value</li> |
| </ul> |
| |
| <p>The <a href="connectivity-header-mapping.html">header mapping</a> applies to the supported MQTT 5 specific headers as well |
| as to the user defined properties, e.g.:</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">"headerMapping"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> |
| </span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{{ header:mqtt.topic }}"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"the-qos"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{{ header:mqtt.qos }}"</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">"{{ header:correlation-id }}"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"device-id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{{ header:device-id-user-defined-property }}"</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> |
| |
| <h4 id="source-acknowledgement-handling">Source acknowledgement handling</h4> |
| |
| <p>For MQTT 5 sources, when configuring |
| <a href="basic-connections.html#source-acknowledgement-requests">acknowledgement requests</a>, consumed messages from the MQTT 5 |
| broker are treated in the following way:</p> |
| |
| <p>For Ditto acknowledgements with successful <a href="protocol-specification-acks.html#combined-status-code">status</a>:</p> |
| <ul> |
| <li>Acknowledges the received MQTT 5 message</li> |
| </ul> |
| |
| <p>For Ditto acknowledgements with mixed successful/failed <a href="protocol-specification-acks.html#combined-status-code">status</a>:</p> |
| <ul> |
| <li>If some of the aggregated <a href="basic-acknowledgements.html#acknowledgements-acks">acknowledgements</a> require redelivery (e.g. based on a timeout): |
| <ul> |
| <li>based on the <a href="#specific-configuration">specificConfig</a> <a href="#reconnectforredelivery">reconnectForDelivery</a> either |
| <ul> |
| <li>closes and reconnects the MQTT connection in order to immediately receive unACKed QoS 1/2 messages again</li> |
| <li>or simply doesn’t acknowledge the received MQTT 5 message resulting in a redelivery of a QoS > 0 message by the MQTT broker</li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li>If none of the aggregated <a href="basic-acknowledgements.html#acknowledgements-acks">acknowledgements</a> require redelivery: |
| <ul> |
| <li>acknowledges the received MQTT 5 message as redelivery does not make sense</li> |
| </ul> |
| </li> |
| </ul> |
| |
| <p>In order to enable acknowledgement processing only for MQTT messages received with QoS 1/2, the following configuration |
| has to be applied:</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">"addresses"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> |
| </span><span class="s2">"<mqtt_topic>"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"..."</span><span class="w"> |
| </span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"authorizationContext"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> |
| </span><span class="s2">"ditto:inbound-auth-subject"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"..."</span><span class="w"> |
| </span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"qos"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"acknowledgementRequests"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> |
| </span><span class="s2">"includes"</span><span class="p">:</span><span class="w"> </span><span class="p">[],</span><span class="w"> |
| </span><span class="s2">"filter"</span><span class="p">:</span><span class="w"> </span><span class="s2">"fn:filter(header:mqtt.qos,'ne','0')"</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="target-format">Target format</h3> |
| |
| <p>For an MQTT connection, the target address is the MQTT topic to publish events and messages to. |
| The target address may contain placeholders; see |
| <a href="basic-connections.html#placeholder-for-target-addresses">placeholders</a> section for more information.</p> |
| |
| <p>Further, <code class="highlighter-rouge">"topics"</code> is a list of strings, each list entry representing a subscription of |
| <a href="protocol-specification-topic.html">Ditto protocol topics</a>.</p> |
| |
| <p>Outbound messages are published to the configured target address if one of the subjects in <code class="highlighter-rouge">"authorizationContext"</code> |
| has READ permission on the thing, which is associated with a message.</p> |
| |
| <p>The additional field <code class="highlighter-rouge">"qos"</code> sets the Quality of Service with which messages are published. |
| Its value can be <code class="highlighter-rouge">0</code> for at-most-once delivery, <code class="highlighter-rouge">1</code> for at-least-once delivery and <code class="highlighter-rouge">2</code> for exactly-once delivery. |
| Support of any Quality of Service depends on the external MQTT broker.</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">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mqtt/topic/of/my/device/{{ thing:id }}"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"topics"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> |
| </span><span class="s2">"_/_/things/twin/events"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"_/_/things/live/messages"</span><span class="w"> |
| </span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"authorizationContext"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"ditto:outbound-auth-subject"</span><span class="p">,</span><span class="w"> </span><span class="s2">"..."</span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"qos"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> |
| </span><span class="p">}</span><span class="w"> |
| </span></code></pre></div></div> |
| |
| <h4 id="target-header-mapping">Target header mapping</h4> |
| |
| <p>MQTT 5 supports so-called user defined properties, which are defined for every message type. |
| The <a href="connectivity-header-mapping.html">header mapping</a> applies to the supported MQTT 5 specific headers as well as to |
| the user defined properties.</p> |
| |
| <p>The following headers have a special meaning in that the values are applied directly to the published message:</p> |
| <ul> |
| <li><code class="highlighter-rouge">mqtt.topic</code>: overwrites the topic configured for the target</li> |
| <li><code class="highlighter-rouge">mqtt.qos</code>: overwrites the qos level configured in the target</li> |
| <li><code class="highlighter-rouge">mqtt.retain</code>: controls whether the MQTT retain flag is set on the published message</li> |
| </ul> |
| |
| <h4 id="target-acknowledgement-handling">Target acknowledgement handling</h4> |
| |
| <p>For MQTT 5 targets, when configuring |
| <a href="basic-connections.html#target-issued-acknowledgement-label">automatically issued acknowledgement labels</a>, requested |
| acknowledgements are produced in the following way:</p> |
| |
| <p>Once the MQTT 5 client signals that the message was acknowledged by the MQTT 5 broker, the following information |
| is mapped to the automatically created <a href="protocol-specification-acks.html#acknowledgement">acknowledgement</a>:</p> |
| <ul> |
| <li>Acknowledgement.status: |
| <ul> |
| <li>will be <code class="highlighter-rouge">200</code>, if the message was successfully ACKed by the MQTT 5 broker</li> |
| <li>will be <code class="highlighter-rouge">503</code>, if the MQTT 5 broker ran into an error before an acknowledgement message was received</li> |
| </ul> |
| </li> |
| <li>Acknowledgement.value: |
| <ul> |
| <li>will be missing, for status <code class="highlighter-rouge">200</code></li> |
| <li>will contain more information, in case that an error <code class="highlighter-rouge">status</code> was set</li> |
| </ul> |
| </li> |
| </ul> |
| |
| <h3 id="specific-configuration">Specific Configuration</h3> |
| |
| <p>The MQTT 5 binding offers additional <a href="basic-connections.html#specific-configuration">specific configurations</a> |
| to apply for the used MQTT client.</p> |
| |
| <p>Overall example JSON of the MQTT <code class="highlighter-rouge">"specificConfig"</code>:</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">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mqtt-example-connection-123"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"connectionType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mqtt"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"connectionStatus"</span><span class="p">:</span><span class="w"> </span><span class="s2">"open"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"failoverEnabled"</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">"uri"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tcp://test.mosquitto.org:1883"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"specificConfig"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> |
| </span><span class="s2">"clientId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my-awesome-mqtt-client-id"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"reconnectForRedelivery"</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">"cleanSession"</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">"separatePublisherClient"</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">"publisherId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my-awesome-mqtt-publisher-client-id"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"reconnectForRedeliveryDelay"</span><span class="p">:</span><span class="w"> </span><span class="s2">"5s"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"lastWillTopic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my/last/will/topic"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"lastWillQos"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"lastWillRetain"</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">"lastWillMessage"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my last will message"</span><span class="w"> |
| </span><span class="p">},</span><span class="w"> |
| </span><span class="s2">"sources"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"..."</span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"targets"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"..."</span><span class="p">]</span><span class="w"> |
| </span><span class="p">}</span><span class="w"> |
| </span></code></pre></div></div> |
| |
| <h4 id="clientid">clientId</h4> |
| |
| <p>Overwrites the default MQTT client id.</p> |
| |
| <p>Default: not set - the ID of the Ditto <a href="basic-connections.html">connection</a> is used as MQTT client ID.</p> |
| |
| <p>If the connection’s <code class="highlighter-rouge">clientCount</code> is 2 or more, |
| the ID of each connectivity service instance is appended to the client ID to prevent clients from having the same |
| ID. Otherwise the broker will disconnect the already-connected client every time another client with the same |
| ID connects.</p> |
| |
| <h4 id="reconnectforredelivery">reconnectForRedelivery</h4> |
| |
| <p>Configures that the MQTT connection re-connects whenever a consumed message (via a connection source) with QoS 1 |
| (“at least once”) 2 (“exactly once”) is processed but cannot be <a href="#source-acknowledgement-handling">acknowledged</a> successfully.<br /> |
| That causes that the MQTT broker will re-publish the message once the connection reconnected. <br /> |
| If configured to <code class="highlighter-rouge">false</code>, the MQTT message is simply acknowledged (<code class="highlighter-rouge">PUBACK</code> or <code class="highlighter-rouge">PUBREC</code>, <code class="highlighter-rouge">PUBREL</code>).</p> |
| |
| <p>Default: <code class="highlighter-rouge">false</code></p> |
| |
| <p>Handle with care:</p> |
| <ul> |
| <li>when set to <code class="highlighter-rouge">true</code>, incoming QoS 0 messages are lost during the reconnection phase</li> |
| <li>when set to <code class="highlighter-rouge">true</code> and there is also an MQTT target configured to publish messages, |
| the messages to be published during the reconnection phase are lost |
| <ul> |
| <li>to fix that, configure <code class="highlighter-rouge">"separatePublisherClient"</code> also to <code class="highlighter-rouge">true</code> in order to publish via another MQTT connection</li> |
| </ul> |
| </li> |
| <li>when set to <code class="highlighter-rouge">false</code>, MQTT messages with QoS 1 and 2 are redelivered based on the MQTT broker’s strategy, |
| but may not be redelivered at all as the MQTT specification does not require unacknowledged messages to be redelivered |
| without reconnection of the client</li> |
| </ul> |
| |
| <h4 id="cleansession">cleanSession</h4> |
| |
| <p>Configure the MQTT client’s <code class="highlighter-rouge">cleanStart</code> flag. (The flag is called <code class="highlighter-rouge">cleanStart</code> but the option is <code class="highlighter-rouge">cleanSession</code> to |
| be consistent with MQTT 3 specific config.)</p> |
| |
| <p>Default: <code class="highlighter-rouge">false</code></p> |
| |
| <h4 id="separatepublisherclient">separatePublisherClient</h4> |
| |
| <p>Configures whether to create a separate physical client and connection to the MQTT broker for publishing messages, or not. |
| If configured to <code class="highlighter-rouge">true</code>, a single Ditto connection would open 2 MQTT connections/sessions: one for subscribing |
| and one for publishing.<br /> |
| If configured to <code class="highlighter-rouge">false</code>, the same MQTT connection/session is used both: for subscribing to messages, and for publishing |
| messages.</p> |
| |
| <p>Default: <code class="highlighter-rouge">false</code></p> |
| |
| <h4 id="publisherid">publisherId</h4> |
| |
| <p>Configures a specific MQTT client ID for the case that <code class="highlighter-rouge">"separatePublisherClient"</code> is enabled.</p> |
| |
| <p>Default:</p> |
| <ul> |
| <li>if client ID is configured, <code class="highlighter-rouge">clientId</code> + <code class="highlighter-rouge">"p"</code></li> |
| <li>if no client ID is configured, <code class="highlighter-rouge">connectionId</code> + <code class="highlighter-rouge">"p"</code></li> |
| </ul> |
| |
| <h4 id="reconnectforredeliverydelay">reconnectForRedeliveryDelay</h4> |
| |
| <p>Configures how long to wait before reconnecting a consumer client for redelivery when <code class="highlighter-rouge">"reconnectForRedelivery"</code> |
| and <code class="highlighter-rouge">separatePublisherClient</code> are both enabled. The minimum value is <code class="highlighter-rouge">1s</code>.</p> |
| |
| <p>Default: <code class="highlighter-rouge">2s</code></p> |
| |
| <h4 id="keepalive">keepAlive</h4> |
| |
| <p>Configures the keep alive time interval (in seconds) in which the client sends a ping to the broker |
| if no other MQTT packets are sent during this period of time. It is used to determine if the connection is still up.</p> |
| |
| <p>Default: <code class="highlighter-rouge">60s</code> <a href="https://hivemq.github.io/hivemq-mqtt-client/docs/mqtt-operations/connect/#keep-alive">see here</a></p> |
| |
| <h4 id="lastwilltopic">lastWillTopic</h4> |
| |
| <p>Configures the topic which should be used on Last Will. This field is mandatory when Last Will should be enabled.</p> |
| |
| <h4 id="lastwillqos">lastWillQos</h4> |
| |
| <p>Configures the QoS which should be used on Last Will:</p> |
| <ul> |
| <li><code class="highlighter-rouge">0</code> = QoS 0 (“at most once”)</li> |
| <li><code class="highlighter-rouge">1</code> = QoS 1 (“at least once”)</li> |
| <li><code class="highlighter-rouge">2</code> = QoS 2 (“exactly once”)</li> |
| </ul> |
| |
| <p>Default: <code class="highlighter-rouge">0</code></p> |
| |
| <h4 id="lastwillretain">lastWillRetain</h4> |
| |
| <p>Configures if clients which are newly subscribed to the topic chosen in <a href="#lastwilltopic">Last Will topic</a> will |
| receive this message immediately after they subscribe.</p> |
| |
| <p>Default: <code class="highlighter-rouge">false</code></p> |
| |
| <h4 id="lastwillmessage">lastWillMessage</h4> |
| |
| <p>Configures the message which should be published when the connection is disconnected ungracefully from the broker. |
| The message will be published as UTF8-encoded text on the topic chosen in <a href="#lastwilltopic">Last Will topic</a>.</p> |
| |
| <p>Default: empty string</p> |
| |
| <h3 id="configure-last-will-message">Configure Last Will message</h3> |
| |
| <p>To notify other clients when the connection is disconnected ungracefully the <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901033">Last Will feature</a> |
| can be used. The message which will be published, is specified in the connection and stored in the broker when it |
| connects. The message contains a topic, retained message flag, QoS, and the text payload to be published. These can be |
| configured in the <a href="#specific-configuration">Specific Configuration</a> of the connection.</p> |
| |
| <div class="alert alert-info" role="alert"><i class="fa fa-info-circle"></i> <b>Note:</b> This feature is enabled if the <em>last will topic</em> is set.</div> |
| |
| <h2 id="establishing-a-connection-to-an-mqtt-5-endpoint">Establishing a connection to an MQTT 5 endpoint</h2> |
| |
| <p>Ditto’s <a href="architecture-services-connectivity.html">Connectivity service</a> is responsible for creating new and managing |
| existing connections.</p> |
| |
| <p>This can be done dynamically at runtime without the need to restart any microservice using a |
| <a href="installation-operating.html#devops-commands">Ditto DevOps command</a>.</p> |
| |
| <p>Example:</p> |
| |
| <p>Connection configuration to create a new MQTT connection:</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">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mqtt-example-connection-12"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"connectionType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mqtt-5"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"connectionStatus"</span><span class="p">:</span><span class="w"> </span><span class="s2">"open"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"failoverEnabled"</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">"uri"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tcp://test.mosquitto.org:1883"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"sources"</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">"addresses"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> |
| </span><span class="s2">"eclipse-ditto-sandbox/#"</span><span class="w"> |
| </span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"authorizationContext"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"ditto:inbound-auth-subject"</span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"qos"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"filters"</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="p">],</span><span class="w"> |
| </span><span class="s2">"targets"</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">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"eclipse-ditto-sandbox/{{ thing:id }}"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"topics"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> |
| </span><span class="s2">"_/_/things/twin/events"</span><span class="w"> |
| </span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"authorizationContext"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"ditto:outbound-auth-subject"</span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"qos"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</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> |
| |
| <h2 id="client-certificate-authentication">Client-certificate authentication</h2> |
| |
| <p>Ditto supports certificate-based authentication for MQTT connections. Consult |
| <a href="connectivity-tls-certificates.html">Certificates for Transport Layer Security</a> |
| for how to set it up.</p> |
| |
| <p>Here is an example MQTT connection, which checks the broker certificate and authenticates by a client certificate.</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">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mqtt-example-connection-124"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"connectionType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mqtt-5"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"connectionStatus"</span><span class="p">:</span><span class="w"> </span><span class="s2">"open"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"failoverEnabled"</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">"uri"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ssl://test.mosquitto.org:8884"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"validateCertificates"</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">"ca"</span><span class="p">:</span><span class="w"> </span><span class="s2">"-----BEGIN CERTIFICATE-----</span><span class="se">\n</span><span class="s2"><test.mosquitto.org certificate></span><span class="se">\n</span><span class="s2">-----END CERTIFICATE-----"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"credentials"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> |
| </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"client-cert"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"cert"</span><span class="p">:</span><span class="w"> </span><span class="s2">"-----BEGIN CERTIFICATE-----</span><span class="se">\n</span><span class="s2"><signed client certificate></span><span class="se">\n</span><span class="s2">-----END CERTIFICATE-----"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"key"</span><span class="p">:</span><span class="w"> </span><span class="s2">"-----BEGIN PRIVATE KEY-----</span><span class="se">\n</span><span class="s2"><client private key></span><span class="se">\n</span><span class="s2">-----END PRIVATE KEY-----"</span><span class="w"> |
| </span><span class="p">},</span><span class="w"> |
| </span><span class="s2">"sources"</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">"addresses"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> |
| </span><span class="s2">"eclipse-ditto-sandbox/#"</span><span class="w"> |
| </span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"authorizationContext"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"ditto:inbound-auth-subject"</span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"qos"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"filters"</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="p">],</span><span class="w"> |
| </span><span class="s2">"targets"</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">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"eclipse-ditto-sandbox/{{ thing:id }}"</span><span class="p">,</span><span class="w"> |
| </span><span class="s2">"topics"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> |
| </span><span class="s2">"_/_/things/twin/events"</span><span class="w"> |
| </span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"authorizationContext"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"ditto:outbound-auth-subject"</span><span class="p">],</span><span class="w"> |
| </span><span class="s2">"qos"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</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> |
| |
| |
| <div class="tags"> |
| |
| <b>Tags: </b> |
| |
| |
| |
| <a href="tag_protocol.html" class="btn btn-default navbar-btn cursorNorm" role="button">protocol</a> |
| |
| |
| |
| <a href="tag_connectivity.html" class="btn btn-default navbar-btn cursorNorm" role="button">connectivity</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"> |
| ©2021 Eclipse Ditto™. |
| Site last generated: Jul 23, 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> |