Skip to main content

Using Azure Storage Queues with a Java Application

Hands-On Lab

 

Photo of Will Boyd

Will Boyd

DevOps Team Lead in Content

Length

01:00:00

Difficulty

Intermediate

Azure Queues provide easy-to-use cloud-based message queueing functionality. Using Azure Queues, you can build your own applications and take advantage of reliable, cloud-based messaging. In this lab, you will have the opportunity to build a simple Java application that utilizes Azure Queues. You will write some Java code to publish messages to an Azure Queue, as well as some code that is capable of consuming those messages.

What are Hands-On Labs?

Hands-On Labs are scenario-based learning environments where learners can practice without consequences. Don't compromise a system or waste money on expensive downloads. Practice real-world skills without the real-world risk, no assembly required.

Using Azure Storage Queues with a Java Application

In this lab, we want to create a scalable, central system to create a log of incoming data in real-time. To do so, we'll be using Azure Queue to create reliable messaging between the systems creating this data and the logging system.

We will build a basic proof-of-concept to allow our developers to interact with the Azure Queue by writing a simple message publisher in Java to publish messages representing items coming in to the warehouse. Then, we'll write some code to consume the messages from the queue and write their data to the console. The consumer code will remove any messages that have been successfully processed.

Keep the following in mind:

  • A storage account already exists for our use. The storage account name begins with the text webconfig.
  • Use a Queue called incoming-items.
  • Some starter code is already located on the Lab VM in the directory /home/cloud_user/content-azurestoragedd-queue-java-lab. Implement the message producer in the file called Producer.java and the consumer in Consumer.java.
  • The starter code contains a Gradle build, which we can use to run our code. From the project root (/home/cloud_user/content-azurestoragedd-queue-java-lab), we can run the Producer with ./gradlew runProducer, and the consumer with ./gradlew runConsumer.
  • We can find a copy of the starter code in GitHub at https://github.com/linuxacademy/content-azurestoragedd-queue-java-lab. Check the end-state branch for an example of one way to complete this lab.

Before We Begin

Before we get started, in an incognito window, we need to log in to the Azure portal with the provided lab credentials. We also need to log into the lab's virtual machine using the provided information, as we will be using the CLI for this lab.

Implement the Message Producer

The first thing we need to do is change the directory to the location of the starter project. The directory is as follows:

cd /home/cloud_user/content-azurestoragedd-queue-java-lab

Here, we need to use ls to list out the information in this directory. The document we need to work with is build.gradle, which we need to edit using the command vi build.gradle.

In this file, locate the dependencies {...}. In here, we need to add the Azure Storage Java API as a dependency:

dependencies {
    implementation 'com.microsoft.azure:azure-storage:4.2.0'
    testImplementation 'junit:junit:4.12'
}

Next, we need to edit the the Producer class.

vi src/main/java/com/linuxacademy/azurestoragedd/queue/Producer.java

Now, for our big chunk of code. This code will implement a basic message producer that publishes a few messages. For example:

package com.linuxacademy.azurestoragedd.queue;

import com.microsoft.azure.storage.*;
import com.microsoft.azure.storage.queue.*;

public class Producer {

    public static void main(String[] args) {
        final String queueName = "incoming-items";
        // Get the storage account name and access key from environment variables.
        String storageAccountName = System.getenv("STORAGE_ACCOUNT_NAME");
        String storageAccountKey = System.getenv("STORAGE_ACCOUNT_KEY");
        // Create the connection string for the storage account.
        final String storageConnectionString = "DefaultEndpointsProtocol=http;" +
            "AccountName=" + storageAccountName + ";" +
            "AccountKey=" + storageAccountKey;
        try {
            //Retrieve the storage account.
            CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);

            // Instantiate a queue client.
            CloudQueueClient queueClient = storageAccount.createCloudQueueClient();

            // Get a reference to the queue, and create it if it does not already exist.
            CloudQueue queue = queueClient.getQueueReference(queueName);
            queue.createIfNotExists();

            // Add some new messages to the queue.
            queue.addMessage(new CloudQueueMessage("Item 4457: Bowling Trophy"));
            queue.addMessage(new CloudQueueMessage("Item 4458: Potato Collection"));
            queue.addMessage(new CloudQueueMessage("Item 4459: 11 Herbs and Spices Recipe"));
            queue.addMessage(new CloudQueueMessage("Item 4460: Ravenclaw's Diadem"));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

Save and exit the document once the code is added, then run the code to verify that it works. To do so, we will need to pass in the storage account name and access key as environment variables. Both of these can be found on the Azure portal. In the resource list, select the storage account and copy the name to replace the storage account name and then under Settings, select Access Keys and select the first key and replace <storage account key>. Make sure it is in quotes:

STORAGE_ACCOUNT_NAME=<storage account name> STORAGE_ACCOUNT_KEY="<storage account key>" ./gradlew runProducer

After running the code, navigate to the Queue on the Azure portal, and we should see the messages created by our code.

Implement the Message Consumer

With the message producer created, we need to move on to edit the message consumer. To do that, use the following command to edit the document:

vi src/main/java/com/linuxacademy/azurestoragedd/queue/Consumer.java

Here, implement a basic consumer that prints all messages to the console, then deletes them from the queue. For example:

package com.linuxacademy.azurestoragedd.queue;

import com.microsoft.azure.storage.*;
import com.microsoft.azure.storage.queue.*;

public class Consumer {

    public static void main(String[] args) {
        final String queueName = "incoming-items";
        // Get the storage account name and access key from environment variables.
        String storageAccountName = System.getenv("STORAGE_ACCOUNT_NAME");
        String storageAccountKey = System.getenv("STORAGE_ACCOUNT_KEY");
        // Create the connection string for the storage account.
        final String storageConnectionString = "DefaultEndpointsProtocol=http;" +
            "AccountName=" + storageAccountName + ";" +
            "AccountKey=" + storageAccountKey;
        try {
            //Retrieve the storage account.
            CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);

            // Instantiate a queue client.
            CloudQueueClient queueClient = storageAccount.createCloudQueueClient();

            // Get a reference to the queue.
            CloudQueue queue = queueClient.getQueueReference(queueName);

            // Process all messages in the queue until no messages remain.
            CloudQueueMessage retrievedMessage;
            do {
                // Retrieve the next available message in the queue.
                retrievedMessage = queue.retrieveMessage();
                if (retrievedMessage != null) {
                    // Process and delete the message.
                    System.out.println(retrievedMessage.getId() + ":" + retrievedMessage.getMessageContentAsString());
                    queue.deleteMessage(retrievedMessage);
                }
            } while (retrievedMessage != null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

Run the code to verify that it works, once again using the information from the Azure portal:

STORAGE_ACCOUNT_NAME=<storage account name> STORAGE_ACCOUNT_KEY="<storage account key>" ./gradlew runConsumer

We receive messages printed to the console after running the code. If we navigate to the Queue on the Azure portal, the messages should no longer be in the queue.

Conclusion

Upon completing this lab, we are now able to use Azure Queue to produce both a message producer and consumer. Congratulations on finishing the lab.