Register Now for EDA Summit 2024 - Virtual EventRegister for Free

Persistence with Queues

7 Minute Read

This tutorial builds on the basic concepts introduced in the publish/subscribe tutorial, and will show you how to send and receive QoS 1 messages using Solace messaging.

Assumptions

This tutorial assumes the following:

  • You are familiar with Solace core concepts.
  • You have access to Solace messaging with the following configuration details:
    • Connectivity information for a Solace message-VPN configured for guaranteed messaging support
    • Enabled client username and password
    • Client-profile enabled with guaranteed messaging permissions.
    • Enabled MQTT service

One simple way to get access to Solace messaging quickly is to create a messaging service in Solace Cloud as outlined here. You can find other ways to get access to Solace messaging below.

Goals

The goal of this tutorial is to understand the following:

  1. How to send a QoS 1 message to Solace messaging.
  2. How to receive a QoS 1 message from Solace messaging.

MQ Telemetry Transport (MQTT) Introduction

MQTT is a standard lightweight protocol for sending and receiving messages. As such, in addition to informatoin provided on the Solace developer portal, you may also look at some external sources for more details about MQTT. The following are good places to start

  1. http://mqtt.org/
  2. https://www.eclipse.org/paho/

Get Solace Messaging

This tutorial requires access Solace PubSub+ messaging and requires that you know several connectivity properties about your Solace messaging. Specifically you need to know the following:

Resources Value Description
Host String This is the address clients use when connecting to the PubSub+ messaging to send and receive messages. (Format: DNS_NAME:Port or IP:Port)
Message VPN String The PubSub+ message router Message VPN that this client should connect to.
Client Username String The client username. (See Notes below)
Client Password String The client password. (See Notes below)

There are several ways you can get access to PubSub+ Messaging and find these required properties.

Option 1: Use PubSub+ Cloud

  • Follow these instructions to quickly spin up a cloud-based PubSub+ messaging service for your applications.

  • The messaging connectivity information is found in the service details in the connectivity tab (shown below). You will need:

    • Host:Port (use the SMF URI)
    • Message VPN
    • Client Username
    • Client Password
Screenshot: Messaging Connectivity Information

Option 2: Start a PubSub+ Software

  • Follow these instructions to start the PubSub+ Software in leading Clouds, Container Platforms or Hypervisors. The tutorials outline where to download and how to install the PubSub+ Software.

  • The messaging connectivity information are the following:

    • Host: <public_ip> (IP address assigned to the VMR in tutorial instructions)

    • Message VPN: default

    • Client Username: sampleUser (can be any value)

    • Client Password: samplePassword (can be any value)

      Note: By default, the PubSub+ Software "default" message VPN has authentication disabled.

Option 3: Get access to a PubSub+ Appliance

  • Contact your PubSub+ appliance administrators and obtain the following:

    • A PubSub+ Message-VPN where you can produce and consume direct and persistent messages
    • The host name or IP address of the Solace appliance hosting your Message-VPN
    • A username and password to access the Solace appliance

Obtaining an MQTT Client Library

Although, you can use any MQTT Client library of your choice to connect to Solace, this tutorial uses the Paho Java Client library. Here are a few easy ways to get the Paho API. The instructions in the Building section assume you're using Gradle and pulling the jars from maven central. If your environment differs then adjust the build instructions appropriately.

Get the API: Using Gradle

    compile("org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0")

Get the API: Using Maven

<dependency>
  <groupId>org.eclipse.paho</groupId>
  <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
  <version>1.1.0</version>
</dependency>

Connecting a session to Solace messaging

The simplest way to connect to a Solace messaging in MQTT is to use an 'MqttClient', as done with other tutorials. So connect the 'MqttClient' as outlined in the publish/subscribe tutorial.

NOTE: If you use the default 'MqttConnectOptions', or set 'MqttConnectOptions.cleanSession' to 'true', as done in the publish/subscribe tutorial, then a Non-Durable (a.k.a. Temporary Endpoint) queue will automatically be created on Solace messaging when the client adds a QoS 1 subscription. Queues are used to store QoS 1 messages providing persistence for the 'MqttClient'. A Non-Durable queue is removed when the 'MqttClient' disconnects, which mean Solace messaging will not retain any messages for the client after it disconnects. Setting the 'MqttConnectOptions.cleanSession' to 'false' will create a Durable queue which will retain messages even after the client disconnects. You can learn more about Solace queue durability from the Endpoint Durability section of Solace Features – Working with Guaranteed Messages.

For the purpose of this tutorial and to clean up resources and state 'MqttConnectOptions.cleanSession' is set to 'true'.

Receiving a QoS 1 message

First connect and subscribe to receive the messages sent to a QoS 1 subscription.

Diagram: Receiving a Message from a Queue

This tutorial uses Quality of Service (QoS) level of 1 (equivalent to Solace “Guaranteed” or “Persistent” messages), which are at least once delivery messages. So first, let’s express interest in the messages by subscribing to a topic filter.

A topic filter in MQTT differs from a Solace SMF topic subscription. Users can learn more about the differences between the two in the Topic Names and Filters section of MQTT Specification Conformance – Operational Behavior.

As with other tutorials, this tutorial receives messages asynchronously through callbacks. So define a callback using the 'MqttCallback' interface as outlined in the publish/subscribe tutorial.

Then you must subscribe to a topic filter with a QoS level of 1 in order to express interest in receiving QoS 1 messages. This tutorial uses the topic '“Q/tutorial”'.

mqttClient.subscribe("Q/tutorial", 1);

The above demonstrates the simplest way to add a QoS 1 subscription with an 'MqttClient'. However, the client is not informed of which QoS is actually granted. This tutorial will confirm if the broker has actually granted the client with QoS 1 subscription. In order do so, we can modify our tutorial to use an 'MqttAsyncClient' instead of an 'MqttClient'. The 'MqttAsyncClient' provides the granted QoS in the response from the subscribe method. You create a client as follows:

MqttAsyncClient mqttClient = new MqttAsyncClient("tcp://" + args[0], "HelloWorldQoS1Subscriber");

We use the 'MqttAsyncClient.subscribe' method, which returns an 'IMqttToken', to track and wait for the subscribe call to complete. Then it is possible to confirm if the client was been granted the QoS 1 level for the topic subscribed.

IMqttToken subToken = mqttClient.subscribe("Q/tutorial", 1);
subToken.waitForCompletion(10000);
if (!subToken.isComplete() || subToken.getException() != null) {
    System.out.println("Error subscribing: " + subToken.getException());
    System.exit(-1);
}
if (subToken.getGrantedQos()[0] != 1) {
    System.out.println("Expected QoS level 1 but got QoS level: " + subToken.getGrantedQos()[0]);
    System.exit(-1);
}

Sending a QoS 1 message

Now it is time to send a QoS 1 message to the subscriber.

Diagram: Sending a Message to a Queue

You must first connect an 'MqttClient' as outlined above in the “Connecting a session to Solace messaging” section. To send a message, you must create a message using the 'MqttMessage' class and set the QoS level. This tutorial will send a message to topic '“Q/tutorial”' with contents “Hello world from MQTT!” and a QoS level of 1, which are at least once delivery messages or Persistent messages in Solace. With a QoS level to 1 set on the message the client will receive acknowledgments from Solace messaging when it has successfully stored the message.

We then use the MQTT client created earlier to publish the message

MqttMessage message = new MqttMessage("Hello world from MQTT!".getBytes());
message.setQos(1);
mqttClient.publish("Q/tutorial", message);

At this point the producer has sent a message to Solace messaging which gets in the Solace messaging spool and your waiting consumer will have received the message and printed its contents to the screen.

Summarizing

The full source code for this example is available on GitHub. Combining the example source code show above results in the following source files:

Getting the Source

Clone the GitHub repository containing the Solace samples.

git clone https://github.com/SolaceSamples/solace-samples-mqtt
cd solace-samples-mqtt

Building

The project uses Gradle. To build, execute the following command.

./gradlew build

This builds all of the Java Samples with OS specific launch scripts. The files are staged in the build/staged directory.

Sample Output

If you start the 'QoS1Consumer' with arguments specifying your Solace messaging connection details, it will connect and wait for a message.

$ ./build/staged/bin/QoS1Consumer <host:port> <client-username> <client-password>
QoS1Consumer initializing...
Connecting to Solace messaging at <host:port>
Connected
Subscribing client to topic: Q/tutorial
Subscribed with QoS level 1 and waiting to receive msgs

Received a Message!
        Time:     2015-10-26 13:50:56.091
        Topic:    Q/tutorial
        Message:  Hello world from MQTT!
        QoS:      1

Exiting

Then you can send a message using the 'QoS1Producer' with the same arguments. If successful, the output for the producer will look like the following:

$ ./build/staged/bin/QoS1Producer <host:port> <client-username> <client-password>
QoS1Producer initializing...
Connecting to Solace messaging at <host:port>
Connected
Publishing message: Hello world from MQTT!
Message published. Exiting

With the message delivered the subscriber output will look like the following:

Received a Message!
    Time:     2015-10-19 11:10:49.929
    Topic:    Q/tutorial
    Message:  Hello world from MQTT!
    QoS:      1

Exiting

The received message is printed to the screen. The message contents were “Hello world from MQTT!” as expected with a QoS level of 1 and the output contains extra information about the Solace message that was received.

You have now successfully sent and received QoS 1 MQTT messages which are equivalent to Solace guaranteed messages.