JMS listener endpoint
The JMS listener endpoint enables developers to write applications that react to messages received via Java Message Service (JMS) - a specification for implementing reliable, asynchronous, loosely-coupled communications. Apache ActiveMQ is Martini's default message broker, however it can be configured to use ActiveMQ Artemis or RabbitMQ instead.
Ad hoc message publishing
JMS messages can be sent by right-clicking on an instance in the Navigator view or Martini Desktop or Online, and choosing Send JMS Message. This prompts a dialog where you can choose a destination and the content you would like to send.
Properties
General configuration
Property | Default | Description |
---|---|---|
Name | (required) | The name of the endpoint. |
Service | (required) | The service to execute when the endpoint is triggered. |
Run As | Anonymous |
The user to run the service in behalf of. This is logged to Tracker. |
Document Type | <Name of endpoint type> | The document type to be used when adding documents to Tracker as this endpoint is triggered. |
Auto Start | true |
Whether or not to automatically start the endpoint upon package startup. |
Log To Tracker | false |
Flag determining whether executions should be logged to Tracker. |
Replicated | true |
If this endpoint is configured on a Martini instance that's running in a cluster, replicated will determine whether to run the endpoint on all instances, or only the elected leader node in the cluster. When this is checked, all instances will run the endpoint. When it's unchecked, only the leader node will run the endpoint. |
JMS listener-specific configuration
Properties | Default | Description |
---|---|---|
Destination | (required) | The JMS destination this endpoint should listen to. |
Transaction Safe | false |
Flag determining whether the service invocation should be wrapped in a transaction. |
Acknowledgement | Auto acknowledge |
For non-transacted JMS session, this property determines how JMS messages are acknowledged. |
Durable | false |
Durable subscription ensures that this endpoint receives messages across restarts. |
Concurrent Consumers | 1 |
The number of concurrent consumers to create for the specified destination. |
Max Concurrent Consumers | 1 |
The number of maximum concurrent consumers to create for the specified destination. If this is higher than the Concurrent Consumers , new consumers will be dynamically created when enough incoming messages are encountered. |
Multiple concurrent consumers for a topic may consume the same message
When the total number of concurrent consumers is greater than 1 for a topic destination, it may lead to concurrent consumption of the same message if your broker is not JMS 2.0 compliant. In JMS 1.1, a topic subscription was not permitted to have more than one consumer at a time. Check your vendor setup measures if it clearly allows this setting.
Multiple concurrent consumers may lose order of messages
Increasing the number of concurrent consumers is recommended to scale the consumption of JMS messages. However, guaranteed ordering of messages is lost when configured to do so. For low-volume queues, it is advisable to stick with 1 consumer.
Service
When the endpoint is triggered, the following variables are exposed to the configured service:
General parameters
Name | Type | Description |
---|---|---|
$trackerId |
java.lang.String |
The Tracker document internal ID. If the endpoint was configured to not track, this value will be null . |
$tracker |
io.toro.martini.tracker.Tracker |
The Tracker object. If the endpoint was configured to not track, this value will be null . |
martiniPackage |
MartiniPackage |
The Martini package that contains the endpoint. |
parameters |
java.util.Map |
A map containing all the endpoint specific parameters. |
properties |
java.util.Map |
A map containing containing all the properties associated with the endpoint. |
JMS listener-specific parameters
Name | Type | Description |
---|---|---|
message |
javax.jms.Message |
The message that triggered this endpoint. |
destination |
javax.jms.Destination |
The destination of the message. |
destinationName |
java.lang.String |
The destination of the message, in String . |
replyTo |
javax.jms.Destination |
The reply destination, or null . |
correlationId |
java.lang.String |
The message correlation ID, or null . |
Depending on the type of message
received by the endpoint, Martini exposes additional variables:
-
Name Type Description bytesMessage
javax.jms.BytesMessage
The bytes message representation of message
. -
Name Type Description mapMessage
javax.jms.MapMessage
The maps message representation of message
. -
Name Type Description objectMessage
javax.jms.ObjectMessage
The object message representation of message
.messageObject
java.io.Serializable
The object contained in this message. -
Name Type Description streamMessage
javax.jms.StreamMessage
The stream message representation of message
. -
Name Type Description textMessage
javax.jms.TextMessage
The text message representation of message
.content
java.lang.String
The content of the message. messageText
java.lang.String
Alias for content
.stringMessage
java.lang.String
Alias for content
.
Example
Gloop as service
Consider this application using Gloop. This is invoked when the JMS destination configured for
the endpoint receives a Message
.
(4) This line sends back the received message
as the reply.
Want more examples?
The distribution ships with a Martini package called examples
, which
contains services (including the above example) demonstrating more use cases.
Groovy script as service
Consider this Groovy script that simply prints the available variables in the context:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
When the endpoint is triggered - in this case, a JMS message sent to the configured destination - the console will show logs similar to the following:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Groovy method as service
We can configure the endpoint to use Groovy methods as services as well. Consider the following example:
1 2 3 4 5 6 7 8 9 10 |
|
Assuming the service DeepThought#respond
is configured in the endpoint, we can trigger it by sending a
message
to the destination topic://toroMartini.universe-questions
. By
invoking the following publisher:
1 2 3 4 5 6 7 8 9 10 11 |
|
Like the info()
method, replyWith()
and publishTo()
are extension methods for JMS
operations. The ask()
method publishes a JMS message, and waits for a reply - which DeepThought
complies with "42".
Destination prefixes
Martini uses the configured application property jms.destination-prefix
as the prefix
(or "toroMartini"
, if none provided) for its JMS destinations. While publishing, the prefix should be
omitted - like in this case: topic://universe-questions
.