Groovy / Maven

Publishing and subscribing to MQTT Topics from a Micronaut Application

Learn how to use Mosquitto as an MQTT broker, create a Micronaut CLI application and publish an MQTT topic, and subscribe to the MQTT topic in a different Micronaut Messaging application.

Sergio del Amo
On this guide
In this section

Getting Started

In this guide, we will create a Micronaut application written in Groovy.

What you will need

To complete this guide, you will need the following:

Solution

We recommend that you follow the instructions in the next sections and create the application step by step. However, you can go right to the completed example.

Test Resources

For this guide, we will use Mosquitto via Test Resources. As described in the MQTT section of the Test Resources documentation, configure a mosquitto container:

Note
This should be done in both apps for this guide.
src/main/resources/application.yml
test-resources:
  containers:
    mosquitto:
      image-name: eclipse-mosquitto
      hostnames:
        - mqtt.host
      exposed-ports:
        - mqtt.port: 1883
      ro-fs-bind:
        - "src/test-resources/mosquitto.conf": /mosquitto/config/mosquitto.conf

And then define the mosquitto configuration file:

src/test-resources/mosquitto.conf
persistence false
allow_anonymous true
connection_messages true
log_type all
listener 1883

As we have defined that Test Resources are shared in the build, both applications will make use of the same instance of Mosquitto.

When running under production, you should replace this property with the location of your production message broker via an environment variable.

MQTT_CLIENT_SERVER_URI=tcp://production-server:1183

Writing the CLI (Command Line Interface) Application

Create an application using the Micronaut Command Line Interface or with Micronaut Launch.

mn create-cli-app example.micronaut.micronautguide \
    --features=mqtt \
    --build=maven --lang=groovy
Note
If you don’t specify the --build argument, Gradle with the Kotlin DSL is used as the build tool.
If you don’t specify the --lang argument, Java is used as the language.
If you don’t specify the --test argument, JUnit is used for Java and Kotlin, and Spock is used for Groovy.

The previous command creates a Micronaut application with the default package example.micronaut in a directory named micronautguide.

Rename this micronautguide directory to cli.

If you use Micronaut Launch, select Micronaut Application as application type and add mqtt features.

Note
If you have an existing Micronaut application and want to add the functionality described here, you can view the dependency and configuration changes from the specified features, and apply those changes to your application.

Create an MqttPublisher

Create an interface to publish MQTT topics:

cli/groovy/src/main/groovy/example/micronaut/TemperatureClient.groovy

Writing the CLI Command

Create an enum to allow the user to submit temperatures in Celsius or Fahrenheit:

cli/groovy/src/main/groovy/example/micronaut/Scale.groovy
package example.micronaut

import groovy.transform.CompileStatic
import io.micronaut.core.annotation.NonNull

import java.util.concurrent.ConcurrentHashMap

@CompileStatic
enum Scale {
    FAHRENHEIT('Fahrenheit'),
    CELSIUS('Celsius')

    private static final Map<String,Scale> ENUM_MAP

    final String name

    Scale(String name) {
        this.name = name
    }

    static {
        Map<String,Scale> map = new ConcurrentHashMap<>()
        for (Scale instance : Scale.values()) {
            map[instance.name] = instance
        }
        ENUM_MAP = Collections.unmodifiableMap(map)
    }

    @NonNull
    static Optional<Scale> of(@NonNull String name) {
        return Optional.ofNullable(ENUM_MAP.get(name))
    }

    @Override
    String toString() {
        name
    }

    static Set<String> candidates() {
        ENUM_MAP.keySet()
    }
}

Create a class to show completion candidates:

cli/groovy/src/main/groovy/example/micronaut/TemperatureScaleCandidates.groovy
package example.micronaut

import groovy.transform.CompileStatic

@CompileStatic
class TemperatureScaleCandidates extends ArrayList<String> {

    TemperatureScaleCandidates() {
        super(Scale.candidates());
    }
}

Replace the command:

cli/groovy/src/main/groovy/example/micronaut/MicronautguideCommand.groovy

Replace the generated test with this:

cli/groovy/src/test/groovy/example/micronaut/MicronautguideCommandSpec.groovy

The MQTT server URI is configured by referencing the properties that were set up for Mosquitto via Test Resources:

cli/src/main/resources/application.properties
mqtt.client.server-uri=tcp://${mqtt.host}:${mqtt.port}
mqtt.client.client-id=${random.uuid}

Writing an MQTT Subscriber Application

Create an application using the Micronaut Command Line Interface or with Micronaut Launch.

mn create-messaging-app example.micronaut.micronautguide \
    --features=mqtt \
    --build=maven --lang=groovy
Note
If you don’t specify the --build argument, Gradle with the Kotlin DSL is used as the build tool.
If you don’t specify the --lang argument, Java is used as the language.
If you don’t specify the --test argument, JUnit is used for Java and Kotlin, and Spock is used for Groovy.

The previous command creates a Micronaut application with the default package example.micronaut in a directory named micronautguide.

Rename this micronautguide directory to app.

If you use Micronaut Launch, select Micronaut Application as application type and add mqtt features.

Note
If you have an existing Micronaut application and want to add the functionality described here, you can view the dependency and configuration changes from the specified features, and apply those changes to your application.

Configuration

The MQTT server URI is configured by referencing the properties that were set up for Mosquitto via Test Resources:

app/src/main/resources/application.properties
mqtt.client.server-uri=tcp://${mqtt.host}:${mqtt.port}
mqtt.client.client-id=${random.uuid}

Create Subscriber

app/groovy/src/main/groovy/example/micronaut/TemperatureListener.groovy

Add test

app/groovy/src/test/groovy/example/micronaut/SubscriptionSpec.groovy

Running the Application

Run the Subscriber App

To run the application, use the ./mvnw mn:run command, which starts the application on port 8080.

Keep it running. Once you publish a topic with the CLI application, you will see a log entry.

Run the CLI

Run the CLI command, which will publish a temperature at startup.

./gradlew run --args="-t 212 -s Fahrenheit"

The subscriber receives the MQTT topic, as you will see in the logs:

12:09:47.280 [MQTT Call: 180d98b5-75b9-41be-a874-295289346592]
    INFO  e.micronaut.TemperatureListener - temperature: 100.00

Next Steps

Read more about Micronaut MQTT.

Help with the Micronaut Framework

The Micronaut Foundation sponsored the creation of this Guide. A variety of consulting and support services are available.

License

Note
All guides are released with an Apache License 2.0 for the code and a Creative Commons Attribution 4.0 license for the writing and media (images).