HiveMQ Enterprise Bridge Extension

The HiveMQ Enterprise Bridge Extension enables HiveMQ to bridge to one or more MQTT brokers for scalable, reliable, and bi-directional exchange of MQTT messages.

HiveMQ Enterprise Bridge Extension Architecture

Features

  • Customizable bidirectional-topic mapping that allows you to configure a set of topic filters that forward matching messages to specific destination topics at another MQTT broker.

  • Fine-grained configuration of the source topic filter and destination topic with the use of all MQTT-specific variables as well as configuration-specific templating.

  • Extensive logging capabilities and useful metrics for monitoring.

Requirements

  • An MQTT bridge broker that runs HiveMQ Professional or Enterprise Edition installation, version 4.4.0 or higher.

  • A remote MQTT message broker that is compliant with the MQTT 5 or MQTT 3.1.1 specification. The remote broker can be a HiveMQ broker or a different broker.

If you do not provide a valid license, HiveMQ automatically uses a free trial license.
Trial licenses for HiveMQ Enterprise Extensions are valid for 5 hours. For more license information or to request an extended evaluation license, contact HiveMQ sales.

Installation

  1. Place your HiveMQ Enterprise Bridge Extension license file (.elic) in the license folder of your HiveMQ installation. (Skip this step if you are using a trial version of the extension).

    All HiveMQ Enterprise Extensions are preinstalled in your HiveMQ release bundle and disabled by default
    └─ <HiveMQ folder>
    ├── README.txt
    ├── audit
    ├── backup
    ├── bin
    ├── conf
    ├── data
    ├── extensions
    │   ├── hivemq-bridge-extension
    │   │   ├── conf
    │   │   │   ├── config.xml (needs to be added by the user)
    │   │   │   ├── config.xsd
    │   │   │   └── examples
    │   │   │       └── ...
    │   │   ├── hivemq-bridge-extension.jar
    │   │   ├── hivemq-extension.xml
    │   │   └── third-party-licenses
    │   │       └── ...
    ├── license
    ├── log
    ├── third-party-licenses
    └── tools
  2. Before you enable the extension, you need to configure the extension to match your individual topics and subscriptions.
    For your convenience, we provide an example configuration conf/examples/config.xml that you can copy and modify as desired.
    The included config.xsd file outlines the schema and elements that can be used in the XML configuration.
    Your completed configuration file must be named config.xml and located at HIVEMQ_HOME/extensions/hivemq-bridge-extension/conf/config.xml
    For detailed information on configuration options, see Configuration.

    Starting with HiveMQ 4.15.0, the configuration for the HiveMQ Bridge Extension is located in HIVEMQ_HOME/extensions/hivemq-bridge-extension/conf/config.xml. Support for the previous location HIVEMQ_HOME/extensions/hivemq-bridge-extension/bridge-configuration.xml will be removed in a future release.

    If applicable, move the configuration from HIVEMQ_HOME/extensions/hivemq-bridge-extension/bridge-configuration.xml to HIVEMQ_HOME/extensions/hivemq-bridge-extension/conf/config.xml.

  3. To enable the HiveMQ Enterprise Bridge Extension, locate the hivemq-bridge-extension folder in the extensions directory of your HiveMQ installation and remove the DISABLED file (if present).

If you want to bridge from an entire HiveMQ cluster, you must install identically configured Enterprise Bridge Extensions on every broker node in the HiveMQ cluster.

To verify the installation and configuration of the bridge extension, check your HiveMQ logs.

You can change the configuration of your HiveMQ Enterprise Bridge Extension during runtime:

  • Add a DISABLED file to the hivemq-bridge-extension folder.

  • Change the configuration of the extension in the conf/config.xml file.

  • Remove the DISABLED file from the hivemq-bridge-extension folder.

Configuration

Minimum Configuration

The minimum bridge extension configuration must contain the following items:

  • A bridge name that is unique within your local node structure.

  • Connection information for the remote broker.

  • A topic filter to forward incoming publishes from MQTT clients on the bridge broker to the remote broker.

To use the bridge extension, you must set up and store a configuration file named config.xml in the hivemq-bridge-extension/conf folder that is located in the extensions directory of your HiveMQ installation.
Example minimum bridge extension configuration
<hivemq-bridge-extension>
    <bridges>
        <bridge>
            <name>your-unique-bridge-name</name>
            <remote-broker>
                <connection>
                    <static>
                        <host>the.hostname.of.remote.broker</host>
                    </static>
                </connection>
            </remote-broker>
            <topics>
                <topic>
                    <filter>a/topic/filter</filter>
                </topic>
            </topics>
        </bridge>
    </bridges>
</hivemq-bridge-extension>

A basic configuration example can be found in the configuration-samples folder of the Enterprise Bridge Extension.

Bridge Extension Configuration Options

The HiveMQ Enterprise Bridge Extension provides many flexible configuration options. You can adjust the settings of each bridge to meet your needs. At least one bridge must be configured in the bridge extension.

All HiveMQ Enterprise Extensions support the use of environment variables. The ${ENV:VARIABLE_NAME} pattern allows you to add placeholders to your configuration XML file that are replaced with the value of an environment variable at runtime. Environment variables cannot be hot reloaded. You must set your environment variables before HiveMQ startup. For more information, see Environment Variables.
Table 1. Bridge Extension Configuration Options
Configuration Required Description

bridge

The configuration settings for one bridge:

  • enabled: Defines whether the selected bridge is enabled.
    The default setting is true.

  • name: The unique identifier of the bridge. The name must be unique per cluster node. The name can contain the following characters: [a-z] [A-Z] [0-9] - _.
    The environment variable ${ENV:HIVEMQ_BRIDGE_NAME} can be used to name the bridge.

remote-broker

Configuration of the remote broker to which bridge clients connect.

  • mqtt: Optional internal settings for the establishment of MQTT connections for bridge clients. Some settings are available for MQTT 5 only.

    • version: The version of the MQTT specification the remote broker supports. Possible values are 5 for MQTT 5 and 3 for MQTT 3.1.1. The default value is 5.

    • flow-control: Restricts the number of inbound and outbound publish requests for each client connection.

      • send-maximum: Defines the maximum number of unacknowledged publish messages that can be present at one time between the bridge client and the remote broker. When the send maximum is reached, no new publish requests are accepted from the client until a PUBACK message is returned by the server.

      • outbound-publish-rate-limit: Defines the maximum number of publish messages a bridge can send per second.

    • clean-start: Defines whether the client wants to start a new session upon reconnection (clean-start = true) or resume a previous session if present (clean-start = false). The default setting is false. For MQTT 3 clients, the clean start setting is used for the clean session.
      NOTE: To prevent loss of messages when the remote broker is not available, the best practice is to resume existing sessions with a clean-start setting of false.

    • session-expiry: The time in seconds until the session of the bridge client expires after the connection is lost or closed. The default setting is 3600 seconds (one hour). Session expiry is only available for MQTT 5 remote brokers.

    • keep-alive: The time in seconds that the broker permits between when a client finishes sending one MQTT packet and starts to send the next. The broker must disconnect a client that does not send a message or a PINGREQ packet in one and a half times the stated keep alive interval. The default setting is 60 seconds.

  • connection: Connection information for the MQTT listener of the remote broker:

    • host: The hostname of the MQTT listener.
      The environment variable ${ENV:REMOTE_BROKER_HOST} can be used to set the hostname.

    • port: The port of the MQTT listener.
      The environment variable ${ENV:REMOTE_BROKER_PORT} can be used to set the listener port. By default, the port is set on 1883.

    • websocket: Optional WebSocket configuration for the MQTT connection:

      • enabled: Defines whether the WebSocket configuration is enabled. The default value is false.

      • server-path: The last part of the path to the WebSocket.

  • authentication: Defines the type of authentication used for the MQTT connection. By default, no values are set:

    • simple-authentication: Optional simple authentication configuration for the MQTT connection of the bridge.

      • client-identifier: Specifies a single client ID for the bridge client.

      • username: The username required to establish the MQTT connection.

      • password: The password required to establish the MQTT connection.

  • tls: Optional TLS configuration for the bridge connection. For more information, see Java Key and Trust Stores.

    • enabled: Defines whether the TLS configuration is used to encrypt communication between the HiveMQ Enterprise Bridge Extension and the remote broker. The default setting is false. To enable your TLS configuration, you must set the enabled parameter to true.

    • keystore: When TLS is enabled, a keystore can be configured. The keystore contains the certificate of the bridge client.

      • path: Location of the P12 or JKS certificates that the keystore uses to store entries.

      • password: The password to the associated keystore.

      • private-key-password: The password that protects the private key of the keystore.

    • truststore: Configuration of an optional truststore that contains the server certificate or the certificate of the certificate authority (CA) that issued the server certificate.

      • path: Location of the P12 or JKS certificates that the truststore uses to store entries.

      • password: The password to the associated truststore.

    • cipher-suites: The sets of cryptographic algorithms the TLS protocol uses to create keys and encrypt information. By default, the bridge extension uses the default cipher suites of your system. The default cipher suites that are available on your system vary based on the Java Runtime Environment.

      • cipher-suite: Optional setting to explicitly define cipher suites. If desired, you can define specific cipher suites to limit the number of suites that are enabled.

    • protocols: The versions of the TLS protocol that can be used to secure communication between the bridge extension and the specified remote broker. By default, the bridge extension enables TLSv1.3 and TLSv1.2.

      • protocol: Optional setting to explicitly define TLS protocols. If desired, you can define one or more specific TLS versions manually. For example, TLSv1.1, TLSv1.2, and TLSv1.3.

loop-prevention

Configuration to reduce the risk of cluster overloads due to infinite message loops. By default, the bridge extension enables loop prevention.
NOTE: Loop prevention utilizes the MQTT 5 feature user properties. Since MQTT 3 does not support user properties, the loop prevention option is ignored in bridge implementations that use MQTT 3.

  • enabled: Optional setting that determines whether the bridge extension prevents the creation of message loops. The default setting is true. To disable loop prevention for the configured bridge, set the enabled parameter to false.

  • hop-count-limit: Sets the maximum number of times the bridge extension processes the same PUBLISH message. The hop count is incremented at the moment a PUBLISH message enters the bridge extension through a bridge client (SUB-mode) or bridge consumer (PUB-mode). The bridge extension uses the hmq-bridge-hop-count user property to count hops (MQTT 5 only). The default hop-count-limit is 1.

topics

Configuration of one or more topics that map MQTT messages for the bridge clients.
At least one topic must be configured.

  • topic: The configuration of one MQTT topic.

    • filter: The UTF-8 string that the broker uses to filter messages for the bridge clients. The topic filter must conform to the standard syntax of MQTT topic filtering paths.

    • mode: Optional setting that defines the method of message transfer. The following options are possible:

      • PUB: In PUB mode, the bridge extension transfers MQTT PUBLISH messages from HiveMQ to the remote broker. The default mode is PUB.

      • SUB: In SUB mode, the bridge extension transfers MQTT PUBLISH messages from the remote broker to HiveMQ.
        NOTE: SUB mode requires the use of an MQTT 5 compliant remote broker. If you configure SUB mode for a remote broker that only supports MQTT 3.1.1, the bridge extension logs a warning and does not start.

    • excludes: Optional setting that excludes one or more topics from bridging. The default setting does not exclude any topics.

    • destination: Optional setting that routes the message for a specific topic to a different destination topic. The default setting uses the original topic.

    • preserve-retained: Optional setting that preserves the retained message flag of messages in the selected data stream. The default setting is 'false'.

Since HiveMQ 4.7, a new excludes tag enables the exclusion of multiple topics per topic filter. The previous exclude tag is now deprecated and can be removed in future HiveMQ versions. Although the old exclude tag is still supported, we strongly recommend that you use the new excludes tag in all your HiveMQ Enterprise Bridge Extension implementations.
Example PUB mode configuration
<topics>
    <topic>
        <filter>+/+/machine/station</filter>
        <mode>PUB</mode>
        <excludes>
            <topic-filter>/voiceStatus/</topic-filter>
            <topic-filter>voicebroker/powerStatus/+</topic-filter>
        </excludes>
        <destination>mytest/{#}</destination>
        <preserve-retained>true</preserve-retained>
    </topic>
</topics>
Example SUB mode configuration
<topics>
    <topic>
        <filter>+/+/machine/station</filter>
        <mode>SUB</mode>
        <excludes>
             <topic-filter>test/+/machine/station</topic-filter>
             <topic-filter>testStatus/+/machine/station</topic-filter>
        </excludes>
        <destination>mytest/{#}</destination>
        <preserve-retained>true</preserve-retained>
    </topic>
</topics>
Example full MQTT 5 configuration
<hivemq-bridge-extension>
    <!-- A list of bridges, at least one bridge must be configured  -->
    <bridges>
        <bridge>
            <enabled>true</enabled>
            <name>a-unique-bridge-name</name>
            <remote-broker>
                <mqtt>
                    <version>5</version>
                    <flow-control>
                            <send-maximum>100</send-maximum>
                            <outbound-publish-rate-limit>100</outbound-publish-rate-limit>
                    </flow-control>
                </mqtt>
                <authentication>
                    <mqtt-simple-authentication>
                        <username>a-username</username>
                        <password>a-user-password</password>
                    </mqtt-simple-authentication>
                </authentication>
                <connection>
                    <static>
                        <host>localhost</host>
                        <port>8000</port>
                    </static>
                    <websocket>
                        <enabled>true</enabled>
                        <server-path>mqtt</server-path>
                    </websocket>
                </connection>
                <mqtt>
                    <clean-start>false</clean-start>
                    <session-expiry>3600</session-expiry>
                    <keep-alive>60</keep-alive>
                </mqtt>
                <tls>
                    <enabled>true</enabled>
                    <keystore>
                        <path>path/to/keystore.jks</path>
                        <password>change-me</password>
                        <private-key-password>change-me-too</private-key-password>
                    </keystore>
                    <truststore>
                        <path>path/to/truststore.jks</path>
                        <password>change-it</password>
                    </truststore>
                    <cipher-suites>
                        <cipher-suite>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384</cipher-suite>
                        <cipher-suite>TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256</cipher-suite>
                        <cipher-suite>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</cipher-suite>
                        <cipher-suite>TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384</cipher-suite>
                        <cipher-suite>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA</cipher-suite>
                        <cipher-suite>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA</cipher-suite>
                        <cipher-suite>TLS_RSA_WITH_AES_128_GCM_SHA256</cipher-suite>
                        <cipher-suite>TLS_RSA_WITH_AES_128_CBC_SHA</cipher-suite>
                        <cipher-suite>TLS_RSA_WITH_AES_256_CBC_SHA</cipher-suite>
                    </cipher-suites>
                    <protocols>
                        <protocol>TLSv1.2</protocol>
                    </protocols>
                </tls>
            </remote-broker>
            <loop-prevention>
                <hop-count-limit>1</hop-count-limit>
                <enabled>true</enabled>
            </loop-prevention>
            <topics>
                <topic>
                    <filter>+/+/machine/station</filter>
                    <mode>PUB</mode>
                    <excludes>
                        <topic-filter>test/+/machine/station</topic-filter>
                        <topic-filter>testStatus/+/machine/station</topic-filter>
                    </excludes>
                    <destination>mytest/{#}</destination>
                    <preserve-retained>false</preserve-retained>
                </topic>
            </topics>
        </bridge>
    </bridges>
</hivemq-bridge-extension>
To ensure proper support of shared subscriptions and consumers, all QoS 2 messages are downgraded to QoS 1 messages in the HiveMQ Enterprise Bridge Extension.
HiveMQ 4.8 adds the ability to use MQTT 3.1.1 clients to bridge to remote brokers that do not provide support for the MQTT 5 specification. For example, HiveMQ 3 and older versions of the Mosquito broker. For more information, see MQTT 3.1.1 Support.

Bridge Extension Configuration with Mutual TLS

The HiveMQ Enterprise Bridge Extension can connect to remote HiveMQ brokers using mutual Transport Layer Security (mTLS). For mTLS, the bridge clients of the HiveMQ bridge extension and the remote HiveMQ broker are required to present valid certificates to each other. Mutual TLS ensures that traffic is secure and trusted in both directions.

When you configure mTLS, the keystore of the bridge extension contains the client certificate. The truststore of the bridge extension contains one or more certificates to verify the identity of the remote HiveMQ broker. For more information, see Java Key and Trust Stores.

For ease of explanation, the following mTLS configuration example uses self-signed certificates for the bridge extension and remote broker. Self-signed certificates are often used in internal networks or test environments. We do not recommend the use of self-signed certificates in production. For production use cases of the HiveMQ Enterprise Bridge Extension, use certificates that are signed by a trusted certificate authority (CA).
Example mTLS configuration with self-signed client certificates

Use of mTLS requires configuration of your remote broker and your bridge extension.

Example remote HiveMQ broker configuration for mTLS
...
<listeners>
    <tls-tcp-listener>
        <name>bridge-mtls-listener</name>
        <port>8883</port>
        <bind-address>0.0.0.0</bind-address>
        <tls>
            <keystore>
                <path>remote-keystore.jks</path>
                <password>server-keystore-password</password>
                <private-key-password>server-keystore-password</private-key-password>
            </keystore>
            <client-authentication-mode>REQUIRED</client-authentication-mode>
            <truststore>
                <path>remote-truststore.jks</path>
                <password>server-truststore-password</password>
            </truststore>
        </tls>
    </tls-tcp-listener>
</listeners>
...
Example HiveMQ Enterprise Bridge Extension conf/config.xml for mTLS
...
<bridge>
    <enabled>true</enabled>
    <name>mtls-bridge</name>
    <remote-broker>
        <connection>
            <static>
                <host>remote.broker</host>
                <port>8883</port>
            </static>
        </connection>
        <tls>
            <enabled>true</enabled>
            <keystore>
                <path>bridge-client-keystore.jks</path>
                <password>client-keystore-password</password>
                <private-key-password>client-keystore-password</private-key-password>
            </keystore>
            <truststore>
                <path>bridge-client-truststore.jks</path>
                <password>client-truststore-password</password>
            </truststore>
        </tls>
    </remote-broker>
</bridge>
...
Example procedure to set up self-signed certificates
  1. Generate a keystore for the remote HiveMQ broker:

    keytool -genkey -keyalg RSA -alias hivemq -keystore remote-keystore.jks -storepass server-keystore-password -dname "CN=remote.server" -validity 3600 -keysize 4096
  2. Generate a keystore for the bridge extension with the client certificate:

    keytool -genkey -keyalg RSA -alias bridge-client -keystore bridge-client-keystore.jks -storepass client-keystore-password -dname "CN=local.client" -validity 3600 -keysize 4096
  3. Export the client certificate from the bridge extension keystore:

    keytool -export -keystore bridge-client-keystore.jks -alias bridge-client -storepass client-keystore-password -file bridge-client.crt
  4. Generate the remote HiveMQ broker truststore and import the client certificate:

    keytool -import -file bridge-client.crt -alias bridge-client -keystore remote-truststore.jks -storepass server-truststore-password
  5. Export the server certificate from the keystore of the remote HiveMQ broker:

    keytool -export -keystore remote-keystore.jks -alias hivemq -storepass server-keystore-password -file remote-server.crt
  6. Generate the bridge extension truststore and import the server certificate:

    keytool -import -file remote-server.crt -alias hivemq -keystore bridge-client-truststore.jks -storepass client-truststore-password

Loop Prevention Configuration (MQTT 5 only)

It is possible to create infinite message loops in your HiveMQ Enterprise Bridge Extension. Unintentional message loops can increase the load on your cluster significantly. To mitigate the possibility of cluster overload due to uncontrolled message loops, the HiveMQ Enterprise Bridge Extension enables basic loop-prevention by default.

The loop-prevention configuration in the bridge extension utilizes an MQTT 5 user property to set duplication limits for PUBLISH messages. Since MQTT 3 does not support user properties, the loop prevention option is ignored in bridge implementations that use MQTT 3.
Hop Counting

The bridge extension tracks the movement (hops) of PUBLISH messages within the bridge extension and stores the count in the hmq-bridge-hop-count user-property of the message.

The hop count is incremented at the moment the PUBLISH message enters the bridge extension via a bridge client (SUB-mode) or bridge consumer (PUB-mode).

If the bridge extension registers an increment in the hmq-bridge-hop-count user property of a PUBLISH message that exceeds the hop-count-limit in your loop-prevention configuration, the extension discards the message.
The bridge extension logs the following metrics for every PUBLISH message that it discards due to an exceeded hop-count-limit:

  • com.hivemq.bridge-extension.{bridge-name}.loop-prevention.publish-dropped.count: Shows you how many PUBLISH messages the extension discarded for a specific bridge due to an exceeded hop-count limit.

  • com.hivemq.bridge-extension.total.loop-prevention.publish-dropped.count: Shows you the total number of PUBLISH messages on all your configured bridges that the extension discarded due to an exceeded hop-count limit. For more information, see Bridge Metrics.

Hop counting provides a simple way to avoid potential loop-creation without the need for complex topic naming configurations.
When you use the default hop-count-limit of 1, no duplicate messages are possible. If you configure the hop-count-limit to a value that is greater than 1, a fixed number of duplicate messages are possible, but no loops can form.

Duplicates can also be prevented through correct configuration with a proper topic structure.
Example Loop Prevention Configuration (MQTT 5 only)
<hivemq-bridge-extension>
    <bridges>
        <bridge>
            ...
            <loop-prevention>
                <!-- default is 1 -->
                <hop-count-limit>1</hop-count-limit>
                <!-- default is true -->
                <enabled>true</enabled>
            </loop-prevention>
            <topics>
                <topic>
                    <filter>#</filter>
                    <mode>PUB</mode>
                </topic>
                <topic>
                    <filter>#</filter>
                    <mode>SUB</mode>
                </topic>
            </topics>
        </bridge>
    </bridges>
</hivemq-bridge-extension>

Hop Count User Property Removal (MQTT 5 only)

In some cases, it can be desirable to remove the hmq-bridge-hop-count user property from PUBLISH messages in your bridge implementation. For example, to remove the hop-count user property for PUBLISH messages that are sent to non-bridge clients.

The HiveMQ Enterprise Bridge Extension provides a global hmq-bridge-hop-count-removal setting that removes the hmq-bridge-hop-count user property from all PUBLISH messages on all your configured bridges.
Hop count user property removal is disabled by default.

When hmq-bridge-hop-count-removal is enabled, you must explicitly configure the bridge clients that you want to exclude from the user property removal.
Only bridge clients with client IDs that match the RegEx pattern you define in the excluded-clients tag continue to receive PUBLISH messages with the hmq-bridge-hop-count user property.

The bridge extension uses a PUBLISH outbound interceptor to remove the user properties. The bridge extension does not add a PublishOutboundInterceptor to bridge clients that match the client ID pattern defined in the excluded-clients tag or to MQTT 3 clients.

Example Hop Count User Property Removal Configuration
<hivemq-bridge-extension>
    <bridges>
        ...
    </bridges>

    <hmq-bridge-hop-count-removal>
        <!-- default is false -->
        <enabled>false</enabled>
        <!-- Defines one or more clients that are excluded from the user-property-removal.
         Configure the pattern for bridge clients that still need to receive the user property -->
        <excluded-clients>
            <excluded-client>
                <client-id-pattern>myBridge-1-.*</client-id-pattern>
            </excluded-client>
        </excluded-clients>
    </hmq-bridge-hop-count-removal>

</hivemq-bridge-extension>

Overlapping Message Configurations in Topic Filters

The HiveMQ Enterprise Bridge Extension applies the first matching topic filter that you define in your configuration. When multiple topic filters are present, the preserve-retained and max-qos settings in the first topic filter that matches a topic are applied.

In the following example, when a message with the topic sub/topic is incoming, the first topic filter is applied. No messages are bridged as retained and max-qos of 1 is applied. The second topic filter is ineffectual.

If a message with the topic my-topic is incoming, the third topic filter is applied. The retain-flag of the incoming message is preserved and max-qos of 0 is applied.

Example Overlapping SUB Topic Filters (no retained messages preserved)
<topic>
    <filter>sub/#</filter>
    <mode>SUB</mode>
    <preserve-retained>false</preserve-retained>
    <max-qos>1</max-qos>
</topic>
<topic>
    <filter>sub/topic3</filter>
    <mode>SUB</mode>
    <preserve-retained>true</preserve-retained>
    <max-qos>0</max-qos>
</topic>
<topic>
    <filter>my-topic</filter>
    <mode>SUB</mode>
    <preserve-retained>true</preserve-retained>
    <max-qos>0</max-qos>
</topic>

Topic Mapping

Topic mapping filters the messaging flow from the source topics to the destination topics. Each topic can consist of one or more topic levels. Topic levels are separated by a forward slash (topic level separator).

Topic mapping functions are bidirectional.
Table 2. Bridge Extension Topic Mapping Options
Topic Filter Setting Description

filter

Defines which messages the bridge extension processes.

excludes

Defines a subset of topics from the topic filter that are not forwarded to the destination topic.

destination

Modifies the selected topic to map to a different topic at the remote broker. This modification is executed before the message is published.

preserve-retained

Defines whether the retained message flags of retained messages in the selected data stream are kept.

<topic>
    <filter>{incomingFilter}</filter>
    <excludes>
        <topic-filter>{excludeFilter}</topic-filter>
    </excludes>
    <destination>{filterDestination}</destination>
    <preserve-retained>false</preserve-retained>
</topic>
Pipe

Modifications of destination tag based on a topic filter:

  • Variables can be used inside the destination and excludes tags

  • Each topic level can be addressed by number, starting with 1

  • Static text can be added

  • A prefix and postfix can be used

Topic Filter Configuration Examples

Forward to a Static Remote Topic Example

Example forward to a static remote topic
<topic>
    <filter>+/status</filter>
    <destination>remote/Data</destination>
</topic>
SimpleForwarding

Exclude Specific Topics Example

Example topic exclusion
<topic>
    <filter>clients/+/+</filter>
    <excludes>
        <topic-filter>client2/status</topic-filter>
    </excludes>
</topic>
  • The bridge extension consumes all topics that match the filter and forwards messages other than messages to the excluded topics to the destination topic.

ExcludeSimpleForwarding

Add Prefix and Postfix as Destination Example

<topic>
    <filter>+/status</filter>
    <destination>prefix/{#}/data</destination>
</topic>
  • The bridge extension consumes all topics that match the filter and uses the full MQTT topic from the client as the destination topic at the remote broker with a prefix and a postfix.

UseTopicPlaceholder

Topic Level Configuration Examples

Parts of Topic Filter as Destination Example

<topic>
    <filter>+/+/+/+</filter>
    <destination>prefix/{1-3}/allData</destination>
</topic>
  • This example uses a four-level incoming filter. The bridge extension forwards all publish topics that match the pattern.

  • For the destination topic at the remote broker, only the first three parts of the local publish topic are used and a prefix and a postfix are added.

UseTopicfilterParts

Prefix, Postfix, and Topic Filter Parts as Destination Example I

<topic>
    <filter>a/+/+/+</filter>
    <excludes>
        <topic-filter>{1}/client2/{#}</topic-filter>
    </excludes>
    <destination>prefix/{2-3}/allData</destination>
</topic>
  • This example uses a four-level incoming filter. The bridge extension forwards all publish topics that match the pattern.

  • For the destination topic at the remote broker, only the second and third parts of the local publish topic are used and a prefix (prefix) and postfix (allData) are added.

  • Messages that have the string client2 at the second level are not forwarded.

UseTopicfilterParts

Prefix, Postfix, and Topic Filter Parts as Destination Example II

<topic>
    <filter>+/+/+/+</filter>
    <destination>prefix/{2}/NEU/{4}/allData</destination>
</topic>
  • This example uses a four-level incoming filter. The bridge extension forwards all publish topics that match the pattern.

  • For the destination topic at the remote broker, only the second and fourth level from the incoming topic are used. The third level is replaced with a constant and a prefix is added.

UseTopicfilterParts

Variables and Topic Filter Parts as Destination Example

<topic>
    <filter>+/+/+/+</filter>
    <destination>prefix/{2}/${bridge.name}/{4}/allData</destination>
</topic>
  • This example uses a four-level incoming filter. The bridge extension forwards all publish topics that match the pattern.

  • For the destination topic at the remote broker, only the second and the fourth level of the incoming topic are used. The third level is replaced with a variable value that contains the bridge name and a prefix is added.

  • A set of 10 variables can be configured. For example, a variable can be configured to use the mqtt clientId, bridgeName, or userName.

UseTopicfilterParts

Additional Topic Level Addressing Examples

  • {2}: Topic filter level 2

  • {2 - #}: Topic filter level 2 and all following levels

  • {#}: Whole topic filter

  • prefix/{#}/postfix: Whole topic filter inside prefix and postfix

  • {1}/A/{2}/B: Level 1 + "/A" + level 2 + "/B"

  • {#}/{1-3): Whole topic filter + level 1, 2, and 3

MQTT 3.1.1. Support

To enable connection to older versions of MQTT brokers and services that do not fully support the MQTT 5 specification, the HiveMQ Enterprise Bridge Extension provides support for MQTT 3.1.1.

In the mqtt tag of your bridge configuration, you can specify the version of the MQTT protocol that the bridge client uses to communicate with the remote broker. By default, the HiveMQ Enterprise Bridge Extension uses MQTT 5. To specify the use of MQTT 3.1.1, set the version value in the mqtt tag to 3.

Example basic MQTT 3 configuration
<hivemq-bridge-extension>
    <bridges>
        <bridge>
            <enabled>true</enabled>
            <name>a-unique-bridge-name</name>
            <remote-broker>
                <mqtt>
                    <version>3</version>
                </mqtt>
                <connection>
                    <static>
                        <host>the.hostname.of.remote.broker</host>
                        <port>1883</port>
                    </static>
                </connection>
                <authentication>
                    <mqtt-simple-authentication>
                        <username>a-username</username>
                        <password>a-user-password</password>
                    </mqtt-simple-authentication>
                </authentication>
            </remote-broker>
            <topics>
                <topic>
                    <filter>bridge/topic/test</filter>
                    <mode>PUB</mode>
                </topic>
            </topics>
        </bridge>
    </bridges>
</hivemq-bridge-extension>
SUB mode in the bridge extension utilizes the MQTT 5 shared subscription feature. MQTT 3.1.1 does not support shared subscriptions. When you configure your bridge with MQTT version 3, you must use PUB mode only. If you configure SUB mode for an MQTT 3.1.1 remote broker, the bridge extension logs a warning and does not start.

Logging Configuration

The HiveMQ Enterprise Bridge Extension can log key activity between the bridge and the remote broker. It is possible to log the following events:

  • Bridge client connects to a remote broker

  • Bridge client disconnects from a remote broker

  • Bridge client sends a PUBLISH message to a remote broker

  • Bridge client sends a SUBSCRIBE message to a remote broker

  • Bridge client receives a message from a remote broker

The <message-log> tag defines the logging behavior for all configured bridges globally.

Table 3. Message Logging Configuration
Configuration Default Value Description

enabled

false

Defines whether the logging configuration is enabled. Possible settings are false and true.

log-level

-

Defines the type of logging information the extension provides. The following options are possible:

  • TRACE

  • DEBUG

  • INFO

  • WARN

  • ERROR

mqtt-packets

-

Defines which operations of the bridge extension are included in the log. Multiple items can be selected:

  • CONNECT

  • DISCONNECT

  • INCOMING-PUBLISH

  • SUBSCRIBE

  • OUTGOING-PUBLISH

Example message logging configuration
<hivemq-bridge-extension>
    <message-log>
        <enabled>true | false</enabled>
        <log-level>DEBUG | INFO | TRACE | ERROR | WARN</log-level>
        <mqtt-packets>CONNECT, DISCONNECT, INCOMING-PUBLISH, SUBSCRIBE, OUTGOING-PUBLISH</mqtt-packets>
    </message-log>
    <bridges>
        ...
    </bridges>
</hivemq-bridge-extension>

Logback Configuration

Change the HIVEMQ_HOME/conf/logback.xml to configure how the HiveMQ Enterprise Bridge Extension logs key activity between the bridge and the remote broker.

Configure logback to write the HiveMQ Bridge Extensions’s <message-log> to a file.
    <appender name="BRIDGE-MQTT-LOG-FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${hivemq.log.folder}/bridge-mqtt-message.log</file>
        <append>true</append>
        <encoder>
            <pattern>%-24(%d)- %msg%n%ex</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>${hivemq.log.folder}/bridge-mqtt-message-%i.log.gz</fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>5</maxIndex>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <maxFileSize>100MB</maxFileSize>
        </triggeringPolicy>
    </appender>

    <logger name="com.hivemq.bridge.log" additivity="false">
        <appender-ref ref="BRIDGE-MQTT-LOG-FILE"/>
    </logger>

HiveMQ Bridge Extension Metrics

The HiveMQ Bridge Extension exposes a dashboard of several useful metrics that you can use to monitor behavior.

Table 4. Metric Types
Metric Type Description

Gauge

A gauge returns a simple value at the point of time the metric was requested.

Counter

A counter is a simple incrementing and decrementing number.

Histogram

A histogram measures the distribution of values in a stream of data. Histograms allow you to measure the min, mean, max, or standard deviation of values and quantiles.

Meter

A meter measures the rate at which a set of events occur. Meters measure mean, 1, 5, and 15-minute moving averages of events.

Timer

A timer is a combination of a histogram and a meter that allows you to measure the duration of a type of event, the rate of occurrence, and capture duration information.

Table 5. Available HiveMQ Bridge Extension Metrics
Metric Type Description

com.hivemq.bridge-extension.total.connect.count

Counter

The total number of MQTT bridge clients the extension connects for all configured bridges

com.hivemq.bridge-extension.total.connect-failed.count

Counter

The total number of MQTT bridge clients the extension is unable to connect for all configured bridges

com.hivemq.bridge-extension.total.disconnect.count

Counter

The total number of MQTT bridge clients the extension disconnects for all configured bridges

com.hivemq.bridge-extension.total.loop-prevention.publish-dropped.count

Counter

The total number of PUBLISH messages for all configured bridges that the extension drops because the messages exceed the hop-count limit

com.hivemq.bridge-extension.total.publish.count

Counter

The total number of PUBLISH messages the extension forwards to remote brokers for all configured bridges

com.hivemq.bridge-extension.total.publish-failed.count

Counter

The total number of PUBLISH messages the extension is unable to forward to remote brokers for all configured bridges

com.hivemq.bridge-extension.total.exclude.count

Counter

The total number of PUBLISH messages to excluded topics that the extension does not forward to a destination topic on a remote broker for all configured bridges

com.hivemq.bridge-extension.total.subscribe.count

Counter

The total number of MQTT bridge clients the extension successfully subscribes on remote brokers in SUB mode for all configured bridges

com.hivemq.bridge-extension.total.subscribe-failed.count

Counter

The total number of MQTT bridge clients the extension is unable to subscribe to remote brokers in SUB mode for all configured bridges

com.hivemq.bridge-extension.total.subscribed-message.count

Counter

The total number of SUB mode messages the extension receives from remote brokers for all configured brokers

com.hivemq.bridge-extension.total.subscribed-message-failed.count

Counter

The total number of SUB mode messages the extension is unable to receive from remote brokers for all configured bridges

com.hivemq.bridge-extension.[bridge-name].exclude.meter

Meter

The rate at which the extension skips PUBLISH messages that are sent to excluded topics on the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].exclude.count

Counter

The number of PUBLISH messages to excluded topics that the extension does not forward to a destination topic on the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].loop-prevention.publish-dropped.count

Counter

The number of PUBLISH messages the extension drops for the indicated bridge because the messages exceed the hop-count limit

com.hivemq.bridge-extension.[bridge-name].publish.meter

Meter

The rate of PUBLISH messages the extension forwards to the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].publish-failed.meter

Meter

The rate of PUBLISH messages the extension is unable to forward to the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].publish.duration

Histogram

The mean duration the extension requires to forward a PUBLISH message to the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].subscribed-message.meter

Meter

The rate at which the extension receives SUB mode messages from the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].subscribed-message-failed.meter

Meter

The rate at which the extension is unable to receive SUB mode messages from the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].subscribed-message.duration

Histogram

The mean duration the extension requires to receive SUB mode messages from the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].[client-id].connect.count

Counter

The number of times the extension connects the indicated MQTT bridge client to the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].[client-id].connect-failed.count

Counter

The number of times the extension is unable to connect the indicated MQTT bridge client to the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].[client-id].disconnect.count

Counter

The number of times the extension disconnects the indicated MQTT bridge client from the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].[client-id].publish.count

Counter

The number of PUBLISH messages the extension forwards with the indicated MQTT bridge client to the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].[client-id].publish-failed.count

Counter

The number of PUBLISH messages the extension is unable to forward with the indicated MQTT bridge client to the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].[client-id].subscribe.count

Counter

The number of times the extension successfully subscribes to the indicated MQTT bridge client in SUB mode to the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].[client-id].subscribe-failed.count

Counter

The number of times the extension is unable to subscribe the indicated MQTT bridge client in SUB mode to the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].[client-id].subscribed-message.count

Counter

The total number of SUB mode messages the extension receives with the indicated MQTT bridge client from the remote broker of the indicated bridge

com.hivemq.bridge-extension.[bridge-name].[client-id].subscribed-message-failed.count

Counter

The total number of PUBLISH messages the extension is unable to receive with the indicated MQTT bridge client from the remote broker of the indicated bridge

The [bridge-name] placeholder is replaced with the configured bridge name.
The [client-id] placeholder is replaced with the MQTT client ID that is used internally for bridging.

Error Handling

  • During the start of the extension, the bridge configuration is validated.

  • If parts of the bridge are incorrectly configured, the extension does not start and a DISABLED flag is set in the extension folder.

  • Setting up the connection to the remote broker is an important part of the configuration.

    • If a connection problem occurs during the extension startup or during runtime, the bridge extension attempts to reconnect internally an unlimited number of times.
      The period between connection retries starts at one second and increases exponentially to a maximum of two minutes.

  • The bridge extension logs errors in the HiveMQ log file.