blob: febc7ae26975e9cd078f0e8534343b89f22f4ace [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="" >
<head>
<title>Core Bridges ยท ActiveMQ Artemis Documentation</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="generator" content="GitBook 3.1.1">
<link rel="stylesheet" href="gitbook/style.css">
<link rel="stylesheet" href="gitbook/gitbook-plugin-highlight/website.css">
<link rel="stylesheet" href="gitbook/gitbook-plugin-search/search.css">
<link rel="stylesheet" href="gitbook/gitbook-plugin-fontsettings/website.css">
<meta name="HandheldFriendly" content="true"/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="gitbook/images/apple-touch-icon-precomposed-152.png">
<link rel="shortcut icon" href="gitbook/images/favicon.ico" type="image/x-icon">
<link rel="next" href="duplicate-detection.html" />
<link rel="prev" href="diverts.html" />
</head>
<body>
<div class="book">
<div class="book-summary">
<div id="book-search-input" role="search">
<input type="text" placeholder="Type to search" />
</div>
<nav role="navigation">
<ul class="summary">
<li class="chapter " data-level="1.1" data-path="./">
<a href="./">
Introduction
</a>
</li>
<li class="chapter " data-level="1.2" data-path="notice.html">
<a href="notice.html">
Legal Notice
</a>
</li>
<li class="chapter " data-level="1.3" data-path="preface.html">
<a href="preface.html">
Preface
</a>
</li>
<li class="chapter " data-level="1.4" data-path="project-info.html">
<a href="project-info.html">
Project Info
</a>
</li>
<li class="chapter " data-level="1.5" data-path="messaging-concepts.html">
<a href="messaging-concepts.html">
Messaging Concepts
</a>
</li>
<li class="chapter " data-level="1.6" data-path="architecture.html">
<a href="architecture.html">
Architecture
</a>
</li>
<li class="chapter " data-level="1.7" data-path="using-server.html">
<a href="using-server.html">
Using the Server
</a>
</li>
<li class="chapter " data-level="1.8" data-path="address-model.html">
<a href="address-model.html">
Address Model
</a>
</li>
<li class="chapter " data-level="1.9" data-path="using-jms.html">
<a href="using-jms.html">
Using JMS
</a>
</li>
<li class="chapter " data-level="1.10" data-path="using-core.html">
<a href="using-core.html">
Using Core
</a>
</li>
<li class="chapter " data-level="1.11" data-path="using-amqp.html">
<a href="using-amqp.html">
Using AMQP
</a>
</li>
<li class="chapter " data-level="1.12" data-path="jms-core-mapping.html">
<a href="jms-core-mapping.html">
Mapping JMS Concepts to the Core API
</a>
</li>
<li class="chapter " data-level="1.13" data-path="client-classpath.html">
<a href="client-classpath.html">
The Client Classpath
</a>
</li>
<li class="chapter " data-level="1.14" data-path="examples.html">
<a href="examples.html">
Examples
</a>
</li>
<li class="chapter " data-level="1.15" data-path="wildcard-routing.html">
<a href="wildcard-routing.html">
Routing Messages With Wild Cards
</a>
</li>
<li class="chapter " data-level="1.16" data-path="wildcard-syntax.html">
<a href="wildcard-syntax.html">
Understanding the Apache ActiveMQ Artemis Wildcard Syntax
</a>
</li>
<li class="chapter " data-level="1.17" data-path="filter-expressions.html">
<a href="filter-expressions.html">
Filter Expressions
</a>
</li>
<li class="chapter " data-level="1.18" data-path="persistence.html">
<a href="persistence.html">
Persistence
</a>
</li>
<li class="chapter " data-level="1.19" data-path="configuring-transports.html">
<a href="configuring-transports.html">
Configuring Transports
</a>
</li>
<li class="chapter " data-level="1.20" data-path="config-reload.html">
<a href="config-reload.html">
Configuration Reload
</a>
</li>
<li class="chapter " data-level="1.21" data-path="connection-ttl.html">
<a href="connection-ttl.html">
Detecting Dead Connections
</a>
</li>
<li class="chapter " data-level="1.22" data-path="slow-consumers.html">
<a href="slow-consumers.html">
Detecting Slow Consumers
</a>
</li>
<li class="chapter " data-level="1.23" data-path="network-isolation.html">
<a href="network-isolation.html">
Avoiding Network Isolation
</a>
</li>
<li class="chapter " data-level="1.24" data-path="transaction-config.html">
<a href="transaction-config.html">
Resource Manager Configuration
</a>
</li>
<li class="chapter " data-level="1.25" data-path="flow-control.html">
<a href="flow-control.html">
Flow Control
</a>
</li>
<li class="chapter " data-level="1.26" data-path="send-guarantees.html">
<a href="send-guarantees.html">
Guarantees of sends and commits
</a>
</li>
<li class="chapter " data-level="1.27" data-path="undelivered-messages.html">
<a href="undelivered-messages.html">
Message Redelivery and Undelivered Messages
</a>
</li>
<li class="chapter " data-level="1.28" data-path="message-expiry.html">
<a href="message-expiry.html">
Message Expiry
</a>
</li>
<li class="chapter " data-level="1.29" data-path="large-messages.html">
<a href="large-messages.html">
Large Messages
</a>
</li>
<li class="chapter " data-level="1.30" data-path="paging.html">
<a href="paging.html">
Paging
</a>
</li>
<li class="chapter " data-level="1.31" data-path="queue-attributes.html">
<a href="queue-attributes.html">
Queue Attributes
</a>
</li>
<li class="chapter " data-level="1.32" data-path="scheduled-messages.html">
<a href="scheduled-messages.html">
Scheduled Messages
</a>
</li>
<li class="chapter " data-level="1.33" data-path="last-value-queues.html">
<a href="last-value-queues.html">
Last-Value Queues
</a>
</li>
<li class="chapter " data-level="1.34" data-path="message-grouping.html">
<a href="message-grouping.html">
Message Grouping
</a>
</li>
<li class="chapter " data-level="1.35" data-path="pre-acknowledge.html">
<a href="pre-acknowledge.html">
Extra Acknowledge Modes
</a>
</li>
<li class="chapter " data-level="1.36" data-path="management.html">
<a href="management.html">
Management
</a>
</li>
<li class="chapter " data-level="1.37" data-path="security.html">
<a href="security.html">
Security
</a>
</li>
<li class="chapter " data-level="1.38" data-path="resource-limits.html">
<a href="resource-limits.html">
Resource Limits
</a>
</li>
<li class="chapter " data-level="1.39" data-path="jms-bridge.html">
<a href="jms-bridge.html">
The JMS Bridge
</a>
</li>
<li class="chapter " data-level="1.40" data-path="client-reconnection.html">
<a href="client-reconnection.html">
Client Reconnection and Session Reattachment
</a>
</li>
<li class="chapter " data-level="1.41" data-path="diverts.html">
<a href="diverts.html">
Diverting and Splitting Message Flows
</a>
</li>
<li class="chapter active" data-level="1.42" data-path="core-bridges.html">
<a href="core-bridges.html">
Core Bridges
</a>
</li>
<li class="chapter " data-level="1.43" data-path="duplicate-detection.html">
<a href="duplicate-detection.html">
Duplicate Message Detection
</a>
</li>
<li class="chapter " data-level="1.44" data-path="clusters.html">
<a href="clusters.html">
Clusters
</a>
</li>
<li class="chapter " data-level="1.45" data-path="ha.html">
<a href="ha.html">
High Availability and Failover
</a>
</li>
<li class="chapter " data-level="1.46" data-path="graceful-shutdown.html">
<a href="graceful-shutdown.html">
Graceful Server Shutdown
</a>
</li>
<li class="chapter " data-level="1.47" data-path="libaio.html">
<a href="libaio.html">
Libaio Native Libraries
</a>
</li>
<li class="chapter " data-level="1.48" data-path="thread-pooling.html">
<a href="thread-pooling.html">
Thread management
</a>
</li>
<li class="chapter " data-level="1.49" data-path="logging.html">
<a href="logging.html">
Logging
</a>
</li>
<li class="chapter " data-level="1.50" data-path="rest.html">
<a href="rest.html">
REST Interface
</a>
</li>
<li class="chapter " data-level="1.51" data-path="embedding-activemq.html">
<a href="embedding-activemq.html">
Embedding Apache ActiveMQ Artemis
</a>
</li>
<li class="chapter " data-level="1.52" data-path="karaf.html">
<a href="karaf.html">
Apache Karaf
</a>
</li>
<li class="chapter " data-level="1.53" data-path="spring-integration.html">
<a href="spring-integration.html">
Spring Integration
</a>
</li>
<li class="chapter " data-level="1.54" data-path="cdi-integration.html">
<a href="cdi-integration.html">
CDI Integration
</a>
</li>
<li class="chapter " data-level="1.55" data-path="intercepting-operations.html">
<a href="intercepting-operations.html">
Intercepting Operations
</a>
</li>
<li class="chapter " data-level="1.56" data-path="protocols-interoperability.html">
<a href="protocols-interoperability.html">
Protocols and Interoperability
</a>
</li>
<li class="chapter " data-level="1.57" data-path="tools.html">
<a href="tools.html">
Tools
</a>
</li>
<li class="chapter " data-level="1.58" data-path="maven-plugin.html">
<a href="maven-plugin.html">
Maven Plugin
</a>
</li>
<li class="chapter " data-level="1.59" data-path="unit-testing.html">
<a href="unit-testing.html">
Unit Testing
</a>
</li>
<li class="chapter " data-level="1.60" data-path="perf-tuning.html">
<a href="perf-tuning.html">
Troubleshooting and Performance Tuning
</a>
</li>
<li class="chapter " data-level="1.61" data-path="configuration-index.html">
<a href="configuration-index.html">
Configuration Reference
</a>
</li>
<li class="chapter " data-level="1.62" data-path="updating-artemis.html">
<a href="updating-artemis.html">
Updating Artemis
</a>
</li>
<li class="divider"></li>
<li>
<a href="https://www.gitbook.com" target="blank" class="gitbook-link">
Published with GitBook
</a>
</li>
</ul>
</nav>
</div>
<div class="book-body">
<div class="body-inner">
<div class="book-header" role="navigation">
<!-- Title -->
<h1>
<i class="fa fa-circle-o-notch fa-spin"></i>
<a href="." >Core Bridges</a>
</h1>
</div>
<div class="page-wrapper" tabindex="-1" role="main">
<div class="page-inner">
<div id="book-search-results">
<div class="search-noresults">
<section class="normal markdown-section">
<h1 id="core-bridges">Core Bridges</h1>
<p>The function of a bridge is to consume messages from a source queue, and
forward them to a target address, typically on a different Apache ActiveMQ Artemis
server.</p>
<p>The source and target servers do not have to be in the same cluster
which makes bridging suitable for reliably sending messages from one
cluster to another, for instance across a WAN, or internet and where the
connection may be unreliable.</p>
<p>The bridge has built in resilience to failure so if the target server
connection is lost, e.g. due to network failure, the bridge will retry
connecting to the target until it comes back online. When it comes back
online it will resume operation as normal.</p>
<p>In summary, bridges are a way to reliably connect two separate Apache ActiveMQ Artemis
servers together. With a core bridge both source and target servers must
be Apache ActiveMQ Artemis servers.</p>
<p>Bridges can be configured to provide <em>once and only once</em> delivery
guarantees even in the event of the failure of the source or the target
server. They do this by using duplicate detection (described in <a href="duplicate-detection.html">Duplicate Detection</a>).</p>
<blockquote>
<p><strong>Note</strong></p>
<p>Although they have similar function, don&apos;t confuse core bridges with
JMS bridges!</p>
<p>Core bridges are for linking an Apache ActiveMQ Artemis node with another Apache ActiveMQ Artemis
node and do not use the JMS API. A JMS Bridge is used for linking any
two JMS 1.1 compliant JMS providers. So, a JMS Bridge could be used
for bridging to or from different JMS compliant messaging system. It&apos;s
always preferable to use a core bridge if you can. Core bridges use
duplicate detection to provide <em>once and only once</em> guarantees. To
provide the same guarantee using a JMS bridge you would have to use XA
which has a higher overhead and is more complex to configure.</p>
</blockquote>
<h2 id="configuring-bridges">Configuring Bridges</h2>
<p>Bridges are configured in <code>broker.xml</code>. Let&apos;s kick off
with an example (this is actually from the bridge example):</p>
<pre><code>&lt;bridge name=&quot;my-bridge&quot;&gt;
&lt;queue-name&gt;jms.queue.sausage-factory&lt;/queue-name&gt;
&lt;forwarding-address&gt;jms.queue.mincing-machine&lt;/forwarding-address&gt;
&lt;filter string=&quot;name=&apos;aardvark&apos;&quot;/&gt;
&lt;transformer-class-name&gt;
org.apache.activemq.artemis.jms.example.HatColourChangeTransformer
&lt;/transformer-class-name&gt;
&lt;retry-interval&gt;1000&lt;/retry-interval&gt;
&lt;ha&gt;true&lt;/ha&gt;
&lt;retry-interval-multiplier&gt;1.0&lt;/retry-interval-multiplier&gt;
&lt;initial-connect-attempts&gt;-1&lt;/initial-connect-attempts&gt;
&lt;reconnect-attempts&gt;-1&lt;/reconnect-attempts&gt;
&lt;failover-on-server-shutdown&gt;false&lt;/failover-on-server-shutdown&gt;
&lt;use-duplicate-detection&gt;true&lt;/use-duplicate-detection&gt;
&lt;confirmation-window-size&gt;10000000&lt;/confirmation-window-size&gt;
&lt;user&gt;foouser&lt;/user&gt;
&lt;password&gt;foopassword&lt;/password&gt;
&lt;static-connectors&gt;
&lt;connector-ref&gt;remote-connector&lt;/connector-ref&gt;
&lt;/static-connectors&gt;
&lt;!-- alternative to static-connectors
&lt;discovery-group-ref discovery-group-name=&quot;bridge-discovery-group&quot;/&gt;
--&gt;
&lt;/bridge&gt;
</code></pre><p>In the above example we have shown all the parameters its possible to
configure for a bridge. In practice you might use many of the defaults
so it won&apos;t be necessary to specify them all explicitly.</p>
<p>Let&apos;s take a look at all the parameters in turn:</p>
<ul>
<li><p><code>name</code> attribute. All bridges must have a unique name in the server.</p>
</li>
<li><p><code>queue-name</code>. This is the unique name of the local queue that the
bridge consumes from, it&apos;s a mandatory parameter.</p>
<p>The queue must already exist by the time the bridge is instantiated
at start-up.</p>
<blockquote>
<p><strong>Note</strong></p>
<p>If you&apos;re using JMS then normally the JMS configuration
<code>activemq-jms.xml</code> is loaded after the core configuration file
<code>broker.xml</code> is loaded. If your bridge is
consuming from a JMS queue then you&apos;ll need to make sure the JMS
queue is also deployed as a core queue in the core configuration.
Take a look at the bridge example for an example of how this is
done.</p>
</blockquote>
</li>
<li><p><code>forwarding-address</code>. This is the address on the target server that
the message will be forwarded to. If a forwarding address is not
specified, then the original address of the message will be
retained.</p>
</li>
<li><p><code>filter-string</code>. An optional filter string can be supplied. If
specified then only messages which match the filter expression
specified in the filter string will be forwarded. The filter string
follows the ActiveMQ Artemis filter expression syntax described in <a href="filter-expressions.html">Filter Expressions</a>.</p>
</li>
<li><p><code>transformer-class-name</code>. An optional transformer-class-name can be
specified. This is the name of a user-defined class which implements
the <code>org.apache.activemq.artemis.core.server.cluster.Transformer</code> interface.</p>
<p>If this is specified then the transformer&apos;s <code>transform()</code> method
will be invoked with the message before it is forwarded. This gives
you the opportunity to transform the message&apos;s header or body before
forwarding it.</p>
</li>
<li><p><code>ha</code>. This optional parameter determines whether or not this bridge
should support high availability. True means it will connect to any
available server in a cluster and support failover. The default
value is <code>false</code>.</p>
</li>
<li><p><code>retry-interval</code>. This optional parameter determines the period in
milliseconds between subsequent reconnection attempts, if the
connection to the target server has failed. The default value is
<code>2000</code>milliseconds.</p>
</li>
<li><p><code>retry-interval-multiplier</code>. This optional parameter determines
determines a multiplier to apply to the time since the last retry to
compute the time to the next retry.</p>
<p>This allows you to implement an <em>exponential backoff</em> between retry
attempts.</p>
<p>Let&apos;s take an example:</p>
<p>If we set <code>retry-interval</code>to <code>1000</code> ms and we set
<code>retry-interval-multiplier</code> to <code>2.0</code>, then, if the first reconnect
attempt fails, we will wait <code>1000</code> ms then <code>2000</code> ms then <code>4000</code> ms
between subsequent reconnection attempts.</p>
<p>The default value is <code>1.0</code> meaning each reconnect attempt is spaced
at equal intervals.</p>
</li>
<li><p><code>initial-connect-attempts</code>. This optional parameter determines the
total number of initial connect attempts the bridge will make before
giving up and shutting down. A value of <code>-1</code> signifies an unlimited
number of attempts. The default value is <code>-1</code>.</p>
</li>
<li><p><code>reconnect-attempts</code>. This optional parameter determines the total
number of reconnect attempts the bridge will make before giving up
and shutting down. A value of <code>-1</code> signifies an unlimited number of
attempts. The default value is <code>-1</code>.</p>
</li>
<li><p><code>failover-on-server-shutdown</code>. This optional parameter determines
whether the bridge will attempt to failover onto a backup server (if
specified) when the target server is cleanly shutdown rather than
crashed.</p>
<p>The bridge connector can specify both a live and a backup server, if
it specifies a backup server and this parameter is set to <code>true</code>
then if the target server is <em>cleanly</em> shutdown the bridge
connection will attempt to failover onto its backup. If the bridge
connector has no backup server configured then this parameter has no
effect.</p>
<p>Sometimes you want a bridge configured with a live and a backup
target server, but you don&apos;t want to failover to the backup if the
live server is simply taken down temporarily for maintenance, this
is when this parameter comes in handy.</p>
<p>The default value for this parameter is <code>false</code>.</p>
</li>
<li><p><code>use-duplicate-detection</code>. This optional parameter determines
whether the bridge will automatically insert a duplicate id property
into each message that it forwards.</p>
<p>Doing so, allows the target server to perform duplicate detection on
messages it receives from the source server. If the connection fails
or server crashes, then, when the bridge resumes it will resend
unacknowledged messages. This might result in duplicate messages
being sent to the target server. By enabling duplicate detection
allows these duplicates to be screened out and ignored.</p>
<p>This allows the bridge to provide a <em>once and only once</em> delivery
guarantee without using heavyweight methods such as XA (see <a href="duplicate-detection.html">Duplicate Detection</a> for
more information).</p>
<p>The default value for this parameter is <code>true</code>.</p>
</li>
<li><p><code>confirmation-window-size</code>. This optional parameter determines the
<code>confirmation-window-size</code> to use for the connection used to forward
messages to the target node. This attribute is described in section
<a href="client-reconnection.html">Reconnection and Session Reattachment</a></p>
<blockquote>
<p><strong>Warning</strong></p>
<p>When using the bridge to forward messages to an address which uses
the <code>BLOCK</code> <code>address-full-policy</code> from a queue which has a
<code>max-size-bytes</code> set it&apos;s important that
<code>confirmation-window-size</code> is less than or equal to
<code>max-size-bytes</code> to prevent the flow of messages from ceasing.</p>
</blockquote>
</li>
<li><p><code>producer-window-size</code>. This optional parameter determines the
producer flow control through the bridge. You usually leave this off
unless you are dealing with huge large messages. </p>
<p>Default=-1 (disabled)</p>
</li>
<li><p><code>user</code>. This optional parameter determines the user name to use when
creating the bridge connection to the remote server. If it is not
specified the default cluster user specified by <code>cluster-user</code> in
<code>broker.xml</code> will be used.</p>
</li>
<li><p><code>password</code>. This optional parameter determines the password to use
when creating the bridge connection to the remote server. If it is
not specified the default cluster password specified by
<code>cluster-password</code> in <code>broker.xml</code> will be used.</p>
</li>
<li><p><code>static-connectors</code> or <code>discovery-group-ref</code>. Pick either of these
options to connect the bridge to the target server.</p>
<p>The <code>static-connectors</code> is a list of <code>connector-ref</code> elements
pointing to <code>connector</code> elements defined elsewhere. A <em>connector</em>
encapsulates knowledge of what transport to use (TCP, SSL, HTTP etc)
as well as the server connection parameters (host, port etc). For
more information about what connectors are and how to configure
them, please see <a href="configuring-transports.html">Configuring the Transport</a>.</p>
<p>The <code>discovery-group-ref</code> element has one attribute -
<code>discovery-group-name</code>. This attribute points to a <code>discovery-group</code>
defined elsewhere. For more information about what discovery-groups
are and how to configure them, please see <a href="clusters.html">Discovery Groups</a>.</p>
</li>
</ul>
</section>
</div>
<div class="search-results">
<div class="has-results">
<h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
<ul class="search-results-list"></ul>
</div>
<div class="no-results">
<h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
</div>
</div>
</div>
</div>
</div>
</div>
<a href="diverts.html" class="navigation navigation-prev " aria-label="Previous page: Diverting and Splitting Message Flows">
<i class="fa fa-angle-left"></i>
</a>
<a href="duplicate-detection.html" class="navigation navigation-next " aria-label="Next page: Duplicate Message Detection">
<i class="fa fa-angle-right"></i>
</a>
</div>
<script>
var gitbook = gitbook || [];
gitbook.push(function() {
gitbook.page.hasChanged({"page":{"title":"Core Bridges","level":"1.42","depth":1,"next":{"title":"Duplicate Message Detection","level":"1.43","depth":1,"path":"duplicate-detection.md","ref":"duplicate-detection.md","articles":[]},"previous":{"title":"Diverting and Splitting Message Flows","level":"1.41","depth":1,"path":"diverts.md","ref":"diverts.md","articles":[]},"dir":"ltr"},"config":{"plugins":[],"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"pluginsConfig":{"highlight":{},"search":{},"lunr":{"maxIndexSize":1000000},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false}},"github":"apache/activemq-artemis","theme":"default","githubHost":"https://github.com/","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{},"title":"ActiveMQ Artemis Documentation","links":{"home":"http://activemq.apache.org/","issues":"http://activemq.apache.org/","contribute":"http://activemq.apache.org/contributing.html"},"gitbook":"3.x.x","description":"ActiveMQ Artemis User Guide and Reference Documentation"},"file":{"path":"core-bridges.md","mtime":"2017-05-03T16:38:23.000Z","type":"markdown"},"gitbook":{"version":"3.1.1","time":"2017-05-15T16:53:09.087Z"},"basePath":".","book":{"language":""}});
});
</script>
</div>
<script src="gitbook/gitbook.js"></script>
<script src="gitbook/theme.js"></script>
<script src="gitbook/gitbook-plugin-search/search-engine.js"></script>
<script src="gitbook/gitbook-plugin-search/search.js"></script>
<script src="gitbook/gitbook-plugin-lunr/lunr.min.js"></script>
<script src="gitbook/gitbook-plugin-lunr/search-lunr.js"></script>
<script src="gitbook/gitbook-plugin-sharing/buttons.js"></script>
<script src="gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
</body>
</html>