Getting Started

This extension allows usage of the HiveMQ MQTT Client inside a Quarkus App, in JVM and Native mode.

Together with the "SmallRye Reactive Messaging MQTT" extension allows usage of a new connector type smallrye-mqtt-hivemq that will use HiveMQ Client instead of Vertx MQTT client.

This adds some benefits to the original SmallRye MQTT:

  • Battle tested MQTT Client outside Vertx landscape

  • Management of external CA file for secure connections with self-signed certificates

  • Backpressure support integrated with MQTT QOS

  • Native mode support

  • DevServices support

  • Automatic and configurable reconnection handling and message redelivery

  • Real Health Check against a configurable topic (defaults to the standard MQTT $SYS/broker/uptime) integrated in Quarkus HealthReport

  • Many others you can read in official documentation here.

Matrix compatibility

Quarkus-hivemq-client version

Quarkus version

HiveMQ client version

2.2.1

3.8.2

1.3.3

2.2.0

3.8.1

1.3.3

2.1.0

3.7.3

1.3.3

2.0.0

3.6.5

1.3.3

1.1.0

2.16.12.Final

1.3.3

1.0.0

2.16.10.Final

1.3.2

Installation

Requirements:

  • Maven 3.8.1+

  • JDK 17+ installed with JAVA_HOME configured appropriately

If you want to use this extension, you need to add the io.quarkiverse.hivemqclient:quarkus-hivemq-client extension first to your build file.

<dependency>
    <groupId>io.quarkiverse.hivemqclient</groupId>
    <artifactId>quarkus-hivemq-client</artifactId>
</dependency>

You can do that by running the following command:

./mvnw quarkus:add-extension -Dextensions="hivemq"
Keep in mind that you will also need io.quarkus:quarkus-smallrye-reactive-messaging-mqtt as a dependency on your build file as others smallrye reactive messaging APIs

Create an application from scratch

You can create a Quarkus application with the HiveMQ-SmallRye extension from scratch by running the following command:

mvn io.quarkus:quarkus-maven-plugin:3.8.1:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=hivemq-quickstart \
    -DclassName="org.acme.quickstart.GreetingResource" \
    -Dextensions="resteasy-reactive,hivemq,smallrye-reactive-messaging-mqtt"

cd hivemq-quickstart

Usage

Add your channels configuration in src/main/resources/application.properties

Then configure your application by adding the HiveMQ connector type:

# Configure the MQTT sink (we write to it)
mp.messaging.outgoing.topic-price.connector=smallrye-mqtt-hivemq
mp.messaging.outgoing.topic-price.topic=prices
mp.messaging.outgoing.topic-price.auto-generated-client-id=true

# Configure the MQTT source (we read from it)
mp.messaging.incoming.prices.connector=smallrye-mqtt-hivemq
mp.messaging.incoming.prices.topic=prices
mp.messaging.incoming.prices.auto-generated-client-id=true
change topic and channels names according to your needs

And then implement your business logic

package incoming;

import org.eclipse.microprofile.reactive.messaging.Incoming;

import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class MqttPriceConsumer {

    @Incoming("prices")
    public void consume(byte[] raw) {
        double price = Double.parseDouble(new String(raw));

        // process your price.
    }

}
package outgoing;

import org.eclipse.microprofile.reactive.messaging.Outgoing;

import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class PriceGenerator {

    private static final Logger LOG = Logger.getLogger(PriceGenerator.class);

    private Random random = new Random();

    @Outgoing("topic-price")
    public Multi<Integer> generate() {
        return Multi.createFrom().ticks().every(Duration.ofSeconds(1))
                .onOverflow().drop()
                .map(tick -> {
                    int price = random.nextInt(100);
                    LOG.infof("Sending price: %d", price);
                    return price;
                });
    }

}
On the above example, we are pushing events into the channel topic-price (which, based on the application.properties, is pointing to the topic prices). On the other hand, we are consuming these events through the channel prices, which is also pointing to the same topic.

Native mode support

There is nothing special on HiveMQ extension that require any additional information than the official one.

Currently, we are using the following images on CI:

ubi-quarkus-native-image
ubi-quarkus-mandrel
ubi-quarkus-graalvmce-builder-image

for example, you can run mvn -V -B -am clean verify -Dnative -Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel:22.3-java17

Dev Services

If no outgoing/incoming host/port is defined then Dev Services will launch a default instance and will connect your channels to the HiveMQ broker.