Message Queue will be discontinued on March 1, 2017. IBM Bluemix (Formerly SoftLayer) will discontinue support on January 31, 2017.

Message Queue: Exploring Topics

Terminology

  • Topic -- a parent resource to which subscriptions belong.
  • Topic tags -- a collection of individual tag names that may be helpful in classifying and grouping topics.
  • Message fields -- a structured key-value collection that can be added to individual messages. Used for variable replacement when a message is sent to subscribers.
  • Subscription -- a mechanism for automatically consuming messages posted to a topic for distribution. Usually takes the form of an HTTP endpoint or a queue already created on your account.
  • Endpoint -- an endpoint is an HTTP or queue-based target to which messages will be delivered.

Creating and Updating a Topic

In Message Queue: Exploring Queues, we created a queue using our authenticated messaging client. In a very similar fashion, we can create and modify a topic.

$messaging = new SoftLayer_Messaging();
if (!$messaging->authenticate(QUEUE_ACCOUNT, QUEUE_USERNAME, QUEUE_API_KEY)) {
    echo "Unable to authenticate!" . PHP_EOL;
    exit;
}
$my_first_topic = $messaging->topic('my_first_topic')->create();

Again, similar to queue creation, topics only require a name to be created. In addition to its name, a topic can also have tags for logical grouping.

$my_first_topic->setTags(array('tag1'));
$my_first_topic->update();

A Subscription & Notification Scenario

Let's say we have an application that is fairly critical to our business. We need a reliable way to broadcast and log critical events throughout the system without adding additional infrastructure of our own.

First, we need a generic catch-all queue. This will allow us to keep a full account of system events and later consume messages in this queue to store them in an "incidents" table in our database.

$messaging->queue('system_events_log')->create();
$logger = new SoftLayer_Messaging_Endpoint_Queue();
$logger->setQueueName('system_events_log');
$messaging->topic('my_first_topic')->subscription()
    ->setEndpointType('queue')
    ->setEndpoint($logger)
    ->create();

This queue will record all messages posted to this topic, even if other potentially unreliable endpoints never get our message.

For email notifications of these events, we can add an HTTP endpoint which reaches out to the SendGrid API. Using variable replacement (which we will see later) we can modify the subject of the email on-the-fly to allow severity concerns to be noticeable at a glance.

    $sendgrid = new SoftLayer_Messaging_Endpoint_Http();
    $sendgrid->setMethod("POST");
    $sendgrid->setUrl("https://sendgrid.com/api/mail.send.json");
    $sendgrid->setHeaders(array("Content-Type" => "application/x-www-form-urlencoded"));
    $sendgrid->setBody("to=ops@example.com&from=logger@example.com&subject={severity}:Logger&text={body}&api_user=youruser&api_key=yourkey");
 
    $messaging->topic('my_first_topic')->subscription()
        ->setEndpointType('http')
        ->setEndpoint($sendgrid)
        ->create();

(Of course you will need to have an active SendGrid account and modify the above to use your own credentials for this to work.) Email is good, but we don't check email all the time. To make sure our on-call staff gets these notifications with enough time to respond, we can add Twilio for text messaging. Using variable replacement again, we can in-line the severity with the body.

    $twilio = new SoftLayer_Messaging_Endpoint_Http();
    $twilio->setMethod("POST");
    $twilio->setUrl("https://youraccount:yourtoken@api.twilio.com/2010-04-01/Accounts/youraccount/SMS/Messages.json");
    $twilio->setHeaders(array("Content-Type" => "application/x-www-form-urlencoded"));
    $twilio->setBody("From=14155550000&To=12145550000&Body={severity}:{body}");
 
    $messaging->topic('my_first_topic')->subscription()
        ->setEndpointType('http')
        ->setEndpoint($twilio)
        ->create();

Publishing Messages to a Topic

Now that we have our topic and subscriptions established, we can finally publish messages. Publishing messages to a topic is almost identical to using a queue.

Let's say our application relies heavily on an active connection to our database. When this connectivity fails, we can simply post a "critical" log message to our topic. This of course would send an email and text message to our oncall ops team and dump the log message into a queue for later accounting.

$my_first_topic->message()
    ->addField('severity', 'Critical')
    ->setBody('Database connectivity has failed!')
    ->create();

Conclusion

The power of topics, subscriptions and variable replacement is largely left up to your imagination. Most services are available through HTTP endpoints and APIs accessible to the SoftLayer Message Queue, it is simply a matter of combining them in a way which fits your business needs. Also note, the Message Queue makes no assumptions about what you are trying to accomplish. In building endpoint objects, make sure you specify the correct content type and fields required to successfully consume the target API or service.