2012-05-04

Brooklyn Messaging Tutorial Part 1

This tutorial will show you how to build a scalable messaging application running in the cloud, using the Brooklyn framework. We will start with configuring and launching a broker in this first part, and continue to develop a custom client entity and also show how to use the different messaging entities available. For this examples we are going to use Apache Qpid, a Java AMQP message broker and some simple client programss using the JMS API. All code samples are written in Groovy 1.8.x with the 1.6.0 JDK and assume a Unix or OSX environment with git and maven available for building and running.

The full code for the application is available on GitHub in the brooklyncentral/brooklyn repository, as the examples/simple-messaging-pubsub includes a deployment descriptor for our example messaging application and simple Publish and Subscribe JMS test client scripts.

Single Broker

The first example will include a Qpid broker, which we will customize to use the Oracle BDB message store as an example of a typical production setup. We will also create a queue for use by a pair of test clients. The QpidBroker entity is created like this, which uses the default configuration, specifying only the AMQP port and creates no queues or topics:

    QpidBroker broker = new QpidBroker(app, amqpPort:5672)

To install the custom configuration files and extra libraries for BDB, we specify some files to copy to the broker installation, using the runtimeFiles property. These files should be available in the classpath of the application when it is running, usually by copying them to the src/main/resources directory. For example, here we copy a custom XML configuration file and a new password file.

    QpidBroker broker = new QpidBroker(app,
            runtimeFiles:[ (QpidBroker.CONFIG_XML):"classpath://custom-config.xml",
                           (QpidBroker.PASSWD):"classpath://passwd" ])

Finally, we come to the complete configuration of our QpidBroker entity using the BDB store. The additional properties here specify the AMQP version and that a queue named testQueue should be created on startup.

    // Configure the Qpid broker entity
    QpidBroker broker = new QpidBroker(app,
            amqpPort:5672,
            amqpVersion:AmqpServer.AMQP_0_10,
            runtimeFiles:[ (QpidBroker.CONFIG_XML):CUSTOM_CONFIG_PATH,
                           (QpidBroker.PASSWD):PASSWD_PATH,
                           ("lib/opt/qpid-bdbstore-0.14.jar"):QPID_BDBSTORE_JAR_PATH ],
                           ("lib/opt/je-5.0.34.jar"):BDBSTORE_JAR_PATH ],
            queue:"testQueue")

Running the Example

You can build and run the example after checking out the code from the Brooklyn repository as follows:

% git clone https://github.com/brooklyncentral/brooklyn.git
% cd brooklyn/examples/simple-messaging-pubsub
% mvn clean install
% cd brooklyn-example-simple-messaging-pubsub
% ./demo-broker.sh

Now, visit the the Brooklyn web console on port 8081 using credentials admin/password. This allows you to view the Brooklyn entities and their current state for debugging.

Note that the installation may take some time, because the default deployment downloads the software from the official repos. You can monitor start-up activity for each entity in the Activity pane in the management console, and see more detail by tailing the log file.

% tail -f brooklyn.log

After starting up, the demo script should display a summary of all the Brooklyn managed entities and their attributes. This will show both the Qpid broker and its child entity, the queue testQueue which was created at startup. The queue entity has sensors that monitor the depth of unread messages, which you can check while running the test client scripts later.

Also visible in this output is the broker URL, which is used to configure JMS clients to connect to this broker. This URL can also be viewed as a sensor attribute in the web console, named broker.url. This sensor is common to all messaging brokers that Brooklyn provides, and is usually accessed by applications to allow them to provide it as a parameter to other entities, as shown in the code fragment below.

    String url = broker.getAttribute(MessageBroker.BROKER_URL)

Using the URL the demo script printed, you can run the test Publish and Subscribe classes, to send messages using the broker. Simply run the scripts in another window, with the provided URL as the only argument. Note that the URLs may be different to those printed below, and that any unquoted & characters must be escaped, if present.

% ./publish.sh "amqp://guest:guest@/localhost?brokerlist='tcp://localhost:5672'"
% ./subscribe.sh "amqp://guest:guest@/localhost?brokerlist='tcp://localhost:5672'"

In the Publish window you should see a log message every time a message is sent, like this:

2012-05-02 14:04:38,521 INFO  Sent message 65
2012-05-02 14:04:39,522 INFO  Sent message 66

Similarly, the Subscribe windows should log on reciept of these messages, as follows:

2012-05-02 14:04:32,522 INFO  got message 41 test message 41
2012-05-02 14:04:33,523 INFO  got message 42 test message 42

Cloud Deployment

With appropriate setup the broker can also be deployed to your favourite cloud. To use Amazon EC2 in Eire, configure the brooklyn.properties file with your credentials and simply run the demo script with the new location as an argument.

% ./demo-broker.sh aws-ec2:eu-west-1

The next part of the tutorial will show how to add a web application client and a custom entity to process messages.