Using the messaging kicker and receiver

This topic describes the messaging kicker and receiver components, which allow an application to asynchronously receive messages.

Overview

The messaging kicker and receiver components are used together to allow an application to start a new piece of request processing when a message arrives on a messaging queue.

Messaging kicker
The messaging kicker component typically runs in the same long-running application that contains the broker that owns the queue being watched. The messaging kicker periodically examines the queue and if a message is available sends an HTTP request to the application that hosts the corresponding messaging receiver.
Messaging receiver
The messaging receiver runs in another application. When the HTTP request is received from the messaging kicker, the messaging receiver reads a message from the queue and fires the message event to allow the message to be processed by an event handler.

The messaging kicker and messaging receiver reside in separate applications. The remainder of this topic describes how the messaging kicker and messaging receiver applications are configured.

Messaging kicker configuration

A messaging kicker can either be placed in the long-running application containing the messaging broker or in a separate application. When run in the same application as a messaging broker, the messaging kicker uses a local interface to determine whether there are messages on the queue. When run in a separate application, the messaging kicker will establish a remote connection to the home broker, for which it needs additional configuration.

The following configuration is required to use the messaging kicker:

  • The application containing the messaging kicker must include the zero.messaging.kicker dependency.
  • The application configuration must define one or more messaging kicker tasks.
  • If the messaging kicker is being run remotely from the messaging broker, the application must include additional connection configuration.

An application containing a messaging kicker can only monitor queues owned by a single messaging broker. A messaging kicker placed in the same long-running application as a messaging broker can only monitor the queues of the local broker. A messaging kicker placed in a separate application can only monitor the queues of the defined home broker.

Messaging kicker task configuration

The application configuration must contain one or more messaging kicker tasks. Each messaging kicker task monitors a single queue but an application can contain multiple kicker tasks, each monitoring different a queue.

The following example contains a messaging kicker task configuration:

/config/timer/tasks/myQueueKicker = { "delay" : 5 }

/config/handlers += [{
    "events" : "timer",
    "handler" : "zero.messaging.kicker.QueueKicker.class",
    "conditions" : "/event/_taskName =~ myQueueKicker",
    "instanceData": {
        "queueName" : "myQueue", 
        "receiverURL" : "http://localhost:8080/messaging/QueueReceiver"
        "config" : {
            # HTTP or HTTPS protocol configuration can be placed here
        }
    }
}]

Each messaging kicker has a unique timer task described by a /config/timer/tasks/ kickerName stanza. The delay value specifies the number of seconds that the timer task will wait between the completion of one messaging kicker invocation and the start of the next.

The corresponding timer event handler describes the activity to be carried out by the messaging kicker task:

  • The conditions clause identifies that this handler is to be used for the named messaging kicker task.
  • queueName value identifies the queue to be monitored.
  • receiverURL value identifies HTTP or HTTPS URL of the messaging receiver application.
  • The optional config map can be used to specify the protocol configuration properties for the outbound HTTP or HTTPS connection to the receiver application. See the zero.core developer's guide for more information about the protocol configuration parameters available for the HTTP and HTTPS support of the Connection API.

It is important to ensure that the receiverURL specified identifies an individual messaging receiver in an individual application process.

An individual messaging queue should not normally be monitored by multiple messaging kicker tasks. Using multiple kicker tasks to monitor a single queue can result in messages being processing by multiple request threads and message ordering will no longer be preserved.

Configuring a remote messaging kicker

A messaging kicker deployed in an application that does not contain a messaging broker requires configuration describing the connection to the broker.

The following example contains a remote connection configuration for a messaging kicker:

/config/messaging/client/homeBroker = "myBroker"

/config/connection/messaging/myBroker = {
    "hostname" : "localhost",
    "port" : 9091
}

/config/messaging/client/kickerCredentials = {
    "userid" : "user1",
    "password" : "pass1"
}

The /config/messaging/client/homeBroker and /config/connection/messaging/ configName stanzas describe the home broker connection properties that the kicker will use to contact the broker owning the queue. A single home broker connection configuration will be used by all kickers running in the application. See Configuring connections to messaging brokers for more information about the home broker configuration.

The /config/messaging/client/kickerCredentials stanza describes the user ID and password that the messaging kicker will use to connect to a secured broker. XOR strings are supported for the password value. A single kicker user ID will be used by all kickers running in the application. The user ID must be given authority to read messages from all the queues being monitored. This stanza should not be specified if the broker is not secured.

The messaging kicker functionality operates when the application runtime is active. The queue will not be monitored when the runtime is in stand-by. If you want the queue to be monitored continuously, either place the messaging kicker component in the application that contains the messaging broker or manually configure the runtime to start immediately. See the developer's guide for more information about runtime management.

Messaging receiver configuration

A messaging receiver resides in an application that includes the zero.messaging.receiver dependency.

The REST endpoint for the messaging receiver is contextRoot /messaging/QueueReceiver. This endpoint must be specified to the corresponding messaging kicker, as the receiverURL value.

An application containing a messaging receiver can process requests from multiple messaging kickers and hence messages from multiple queues. The message event handler definition is used to route incoming messages to the appropriate application logic.

The following example contains a simple receiver configuration:

/config/messaging/client/homeBroker = "myBroker"

/config/connection/messaging/myBroker = {
    "hostname" : "localhost",
    "port" : 9091
}

/config/handlers += [{
  "events" : "message",
  "handler" : "myMessageHandler.groovy",
  "conditions" : "/request/messaging/queue =~ myQueue"
}]

/config/messaging/client/receiverCredentials = {
    "userid" : "user1",
    "password" : "pass1"
}

The following notes describe the stanzas in the above configuration:

  • The /config/messaging/client/homeBroker and /config/connection/messaging/ configName stanzas describe the home broker connection properties that the receiver will use to contact the broker owning the queue. The messaging receiver must use the same home broker as the corresponding messaging kicker.
  • The message event handler describes the handler that should be invoked when a message has arrived on the named queue. The message event is described below.
  • The /config/messaging/client/receiverCredentials stanza describes the user ID and password that the messaging receiver will use to connect to a secured broker. XOR strings are supported for the password value. A single receiver user ID will be used by all message handlers in the application. The user ID must be given authority to read messages from all the queues being monitored. This stanza should not be specified if the broker is not secured.

The conditions clause can be used to select a message event handler based on the name of the queue or criteria such as the message headers. It is important that the conditions clauses are written to ensure that any message that may arrive on the queue will be matched by at least one message handler. If a message matches more than one conditions clause, it will be processed by all matching handlers in a single unit of work. If no matching message hander is registered, the receiver will be unable to deliver the message and will signal a failure to the messaging kicker. The message will remain on the queue and the kicker will continue to attempt to notify the receiver until the message has been delivered.

The message event

The message event is fired by the messaging receiver when a new message has arrived on a queue. The application logic required to process the message is implemented as a message event handler, in as similar way to a handler for an HTTP request.

When the message event is fired, the following values are available in the global context. These values may be used in the conditions clause to select a suitable event handler or to access the details of the message in the onMessage() implementation.

/request/messaging/kicker
The name of the message kicker.
/request/messaging/queue
The name of the queue on which the message arrived.
/request/messaging/message
The javax.jms.Message that has arrived.
/request/messaging/headers/ headerName
Message properties.

The zero.messaging.receiver dependency includes (via zero.connection.jms) a type handler which can be used to access the contents of the response body without explicitly using the javax.jms.* API in the application code. See the zero.connection.jms developer's guide for more information about working with javax.jms.Message objects in the global context and with the Connection API.

The messaging receiver places information in two additional global context keys to allow the optional reuseSession behaviour of the messaging protocol to operate. /request/connection/messaging/connectionConfig will contain the broker connection configuration name used by the messaging receiver. /request/connection/messaging/session will contain the instance of javax.jms.Session being used by the messaging receiver.

Version 1.1.0.0.21442