MQTT Ant task

Building an Ant Task

With an interest in publish-subscribe with MQTT , it seems a natural choice to try and get  some other tools I use to talk to the microbroker we’ve got running. I chose Ant, partly because I use it for loads of things and because there is a handy java client library for MQTT to make things easier.

First step was an Ant task that could connect to the broker and publish a message to a given topic.Ok, so googled to find out how to make up an Ant addin and, luckily, there is a great tutorial at Roy Lyberger at developer.com that got me up to speed with how it all works. So, with the hello-world-with-parameters example under my belt from page 2 with some minor name mods to use my package name and an optimistic addin name, I had this code working:

package org.btiowl.ant.taskdefs;

import org.apache.tools.ant.Task;
import org.apache.tools.ant.Project;

public class MQTTAnt extends Task {
   private String name=null;
   public void setName(String name) {
      this.name = name;
   }

   public String getName() {
      return name;
   }

   public void execute() {
      if (name != null && name.length() > 0) {
         log("Hello, " + name + "!", Project.MSG_INFO);
      }
      else {
         log("Hello, World!", Project.MSG_INFO);
      }
   }

}

and I could call it in Ant using:

<target name="demo">
    <mqttant name="Bob TI Owl"/>
</target>
<target name=”demo”>
<mqttant name=”Bob TI Owl”
topic=”mqttant”
payload=”Hello Tue”/>
</target>

MQTT Publish

Next, I needed to add the necessary magic to the execute method and a few more parameters. Off to the MQTT site (where you can also download their excellent microbroker) and  downloaded the IA92 java client – adding /J2SE/wmqtt.jar into myclasspath.

The mqtt publish cycle is pretty simple: connect,publish,disconnect

client = new MqttClient(URL); 
client.connect(NAME, CLEAN_START, KEEP_ALIVE );

These lines connect to the broker, the URL is something like “tcp://localhost:1883” or where ever your broker is, the NAME is a unique name for the client, such as “mqttant”, CLEAN_START throws away any history the broker may have on each connection and KEEP_ALIVE is the number of seconds between pings from the client expected by the broker.

client.publish(TOPIC,PAYLOAD.getBytes(),QOS,RETAINED);

This line publishes the PAYLOAD string as a byte array to a given TOPIC. The QOS level is an integer an gives the level of transport. I’m using a qos of 0, which is  “fire and forget”. See here for a full explanation of other qos levels.

The RETAINED flag if true is a feature that tells the broker to retain the last message. This means that a client connecting and subscribing to our topic would always get the last message we sent . This is a good idea in an Ant build but works equally well for other sporadic publishers.

Using the hello-world-with-parameters above as a template, I added parameters for the url,topic and payload along with some defaults, getters and setters and slotted the mqtt code into the execute method.  I’ve added a bit of error handling so it doesn’t instantly blow up if for instance it can’t find the broker. Feel free to add better java. Anyway, the resulting code looked like so:

package org.btiowl.ant.taskdefs;

import org.apache.tools.ant.Task;
import org.apache.tools.ant.Project;
import com.ibm.mqtt.MqttClient;
import com.ibm.mqtt.MqttException;

public class MQTTAnt extends Task {
   private final static boolean CLEAN_START = true;
   private final static boolean RETAINED = true;
   private final static short KEEP_ALIVE = 30;
   private final static short QOS = 0;

   private String name="mqttant";
   private String url="tcp://localhost:1883";
   private String topic="mqttant";
   private String payload="hello from ant";
   private MqttClient client=null;

   public void setPayload(String payload) {
      this.payload = payload;
   }

   public String getPayload() {
      return payload;
   }

  public void setName(String name) {
      this.name = name;
   }

   public String getName() {
      return name;
   }

  public void setUrl(String url) {
      this.url = url;
   }

   public String getUrl() {
      return url;
   }

  public void setTopic(String topic) {
      this.topic = topic;
   }

   public String getTopic() {
      return topic;
   }

   public void execute() {
		try{
		client = new MqttClient(url);
		client.connect(name, CLEAN_START, KEEP_ALIVE );
		client.publish(topic,payload.getBytes(),QOS,RETAINED);
		log("Message published to mqtt", Project.MSG_INFO);
           }
        catch( MqttException exception )
           {
          log("MQTT error: " +exception.getCause(),Project.MSG_WARN);
           }
        finally {
           try {
               	if (client != null) {
               	client.disconnect();
        		}
           }
        catch (MqttException exception) {
          log("MQTT error: " +exception.getCause(),Project.MSG_WARN);
           }
       }
   }
}

If there is a problem I just output what I can as a warning and carry on. For an Ant task I don’t want it to stop the build if this bit fails. That’s it – I can now publish to a topic from my build like so:

<target name="demo">
      <mqttant name="Bob"
      topic="mqttant"
      payload="Hello from Ant"/>
</target>

With a bit more work I could create a subscription, or set up a listener maybe, which actually may be better. This will do for a start 🙂

One thought on “MQTT Ant task

  1. Very cool. Back when I worked for IBM and ran the Microbroker build, I set up the Ant build (in a v similar way) to publish the build status at every step, including the unit test results. If it passed unit testing, it also published (retained) the build ID to another topic. Anyone wondering what the last good build was could subscribe to that and get updates as they happened. Happy days. I wonder how much of that is still in place.

Comments are closed.