JMS Transport
Java Message Service (JMS) is a widely used API in Java-based Message Oriented Middleware(MOM) applications. It facilitates loosely coupled, reliable, and asynchronous communication between different components of a distributed application.
JMS supports two asynchronous communication models for messaging as follows:
- Point-to-point model - In this model message communication happens from one JMS client to another JMS client through a dedicated queue.
- Publish and subscribe model - In this model message communication happens from one JMS client(publisher) to many JMS clients(subscribers) through a topic.
JMS supports two models for messaging as follows:
- Queues : point-to-point
- Topics : publish and subscribe
The ESB Profile of WSO2 EI supports the following messaging features introduced with JMS 2.0:
- Shared Topic Subscription
- JMSX Delivery Count
- JMS Message Delivery Delay
The Java Message Service (JMS) transport in WSO2 Enterprise Integrator(WSO2 EI) allows you to easily send and receive messages to queues and topics of any JMS service that implements the JMS specification.
The JMS transport implementation comes from the WS-Commons Transports project, and it makes use of JNDI to connect to various JMS brokers. As a result, WSO2 EI can work with any JMS broker that offers JNDI support. All the relevant classes are packed into the axis2-transport-jms-<version>.jar
and the classes org.apache.axis2.transport.jms.JMSListener and org.apache.axis2.transport.jms.JMSSender act as the transport receiver and sender respectively.
The JMS transport implementation requires an active JMS server instance to be able to receive and send messages. We recommend using WSO2 Message Broker or Apache ActiveMQ, but other implementations such as Apache Qpid and Tibco are also supported. For information on how to configure the JMS transport with the most common broker servers that can be integrated with WSO2 EI, see Configuring the JMS Transport.
JMS connection factory parameters
Configuration parameters for the JMS receiver and the sender are XML fragments that represent JMS connection factories. Following is a typical JMS configuration that uses WSO2 Message Broker as the message broker:
<parameter name="myTopicConnectionFactory"> <parameter name="java.naming.factory.initial">org.wso2.andes.jndi.PropertiesFileInitialContextFactory</parameter> <parameter name="java.naming.provider.url">conf/jndi.properties</parameter> <parameter name="transport.jms.ConnectionFactoryJNDIName">TopicConnectionFactory</parameter> <parameter name="transport.jms.ConnectionFactoryType">topic</parameter> </parameter>
This is a bare minimal JMS connection factory configuration that consists of four connection factory parameters. The following table describes each JMS connection factory parameter in detail:
Tip
In transport parameter tables, literals displayed in italic mode under the Possible Values column should be considered as fixed literal constant values. Those values can be directly used in transport configurations.
Parameter Name | Description | Required | Possible Values | Default Value |
---|---|---|---|---|
| JNDI initial context factory class. The class must implement the | Yes | A valid class name | org.apache.activemq.jndi.ActiveMQInitialContextFactory |
| URL of the JNDI provider. | Yes | A valid URL | tcp://localhost:61616 |
| JNDI Username. | No | ||
| JNDI password. | No | ||
| Preferred mode of transactionality. Note In WSO2 EI, JMS transactions only work with either the Callout mediator or the Call mediator in blocking mode. | No | none: Disables transactions in the JMS transport local: Enables local JMS session transactions jta: Enables global JTA transactions | none |
| JNDI name to be used to require user transaction. | No | java:comp/UserTransaction | |
| Whether caching for user transactions should be enabled or not. | No | true, false | true |
| Whether the JMS session should be transacted or not. | No | true, false | true if transactionality is 'local' |
| JMS session acknowledgment mode. | No |
Also see JMS Message Delivery Reliability and Acknowledgement Patterns. | AUTO_ACKNOWLEDGE |
| The JNDI name of the connection factory. | Yes | QueueConnectionFactory, TopicConnectionFactory | ConnectionFactory |
| Type of the connection factory. | No | queue, topic | queue |
| JMS API version. | No | 1.1, 1.0.2b | 1.1 |
| The JMS connection username. | No | ||
| The JMS connection password. | No | ||
| The JNDI name of the destination. | No | Defaults to service name | |
| Type of the destination. | No | queue, topic | queue |
| JNDI name of the default reply destination. | No | ||
| Type of the reply destination. | No | queue, topic | Defaults to the type of the destination |
| Message selector implementation. | No | ||
| Whether the connection factory is subscription durable or not. | No | true, false | false |
transport.jms.DurableSubscriberClientID | The ClientId parameter when using durable subscriptions | Required if the value specified as | ||
| The name of the durable subscriber. | Required if the value | ||
| Whether the messages should be published by the same connection they were received. | No | true, false | false |
| The cache level, with which JMS objects should be cached at start up. You can configure this in the Example: <endpoint> <address uri="jms:/example.MyQueue?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.wso2.andes.jndi.PropertiesFileInitialContextFactory&java.naming.provider.url=repository/conf/jndi.properties&transport.jms.DestinationType=queue&transport.jms.CacheLevel=producer"/> </endpoint> Else, you can configure as a proxy service parameter, if WSO2 EI acts as a consumer. Following are the possible values for this parameter and the description of each:
| No | none, connection, session, consumer, producer, auto | auto |
| Time to wait for a JMS message during polling. Set this parameter value to a negative integer to wait indefinitely. Set to zero to prevent waiting. | No | Number of milliseconds to wait | 1000 ms |
| Number of concurrent threads to be started to consume messages when polling. | No | Any positive integer - For topics this must be always 1 | 1 |
| Maximum number of concurrent threads to use during polling. | No | Any positive integer - For topics this must be always 1 | 1 |
| The number of idle runs per thread before it dies out. | No | Any positive integer | 10 |
| The maximum number of successful message receipts per thread. | No | Any positive integer - Use -1 to indicate infinity | -1 |
| Initial reconnection attempts duration in milliseconds. | No | Any positive integer | 10000 ms |
| Factor by which the reconnection duration will be increased. | No | Any positive integer | 2 |
| Maximum reconnection duration in milliseconds. | No | 3600000 ms (1 hr) | |
transport.jms.ReconnectInterval | Reconnection interval in milliseconds. | No | >3600000 ms (1 hr) | |
| Maximum cached JMS connections in the producer level. | No | Any positive integer value | 10 |
| Number of retries on consume errors before sleep delay kicks in. | No | Any positive integer value | 20 |
| Sleep delay when a consume error is encountered (in milliseconds). | No | Any positive integer value | 100 ms |
| Factor by which the consume error retry sleep will be increased. | No | Any positive integer value | 2.0 |
transport.jms.MaxConsumeErrorRetryCount | The maximum number of times the consumer should retry upon receiving a consumer error. You need to introduce this parameter only if the Broker has issues in notifying the Exception Listeners about the exceptions occurred. | No | Any positive integer value | -1 |
JMS transport implementation has some parameters that should be configured at service level. For example, parameters that should be configured in the service XML files of individual services.
Service level JMS configuration parameters
Following are some of the common parameters you can configure at the service level.
Parameter Name | Description | Required | Possible Values |
---|---|---|---|
| Name of the JMS connection factory the service should use. | No | A name of an already defined connection factory |
| JMS EPR to be published in the WSDL. | No | A JMS EPR |
transport.jms.ContentType | Specifies how the transport listener should determine the content type of received messages. | No | A simple string value, in which case the transport listener assumes that the received messages always have the specified content type, or a set of rules. For more information, see http://axis.apache.org/axis2/java/transports/jms.html#Service_configuration. |
transport.jms.MessagePropertyHyphens | Specifies the action to be taken when there are JMS Message property names that contain hyphens. | No |
|
For information on how to tune the JMS transport for better performance, see Tuning the JMS Transport.
JMS MapMessage support
In the ESB Profile of WSO2 Enterprise Integrator (WSO2 EI), the JMS transport supports producing and consuming JMS MapMessage objects, which send a set of name/value pairs.
Producing a MapMessage
To send a MapMessage from a proxy service or API to a queue, construct an XML payload using the PayloadFactor mediator (or another method) in the following structure, and send it to a JMS endpoint:
<JMSMap xmlns="http://axis.apache.org/axis2/java/transports/jms/map-payload"> <name1>value1</name1> <name2>value2</name2> <name3>value3</name3> </JMSMap>
The JMS sender will then produce the equivalent MapMessage object:
MapMessage message = session.createMapMessage(); message.setString("name1", "value1"); message.setString("name2", "value2"); message.setString("name3", "value3");
Consuming a MapMessage
When a proxy service receives a JMS MapMessage via a JMS broker, it will convert it to an XML message like this:
<JMSMap xmlns="http://axis.apache.org/axis2/java/transports/jms/map-payload"> <name1>value1</name1> <name2>value2</name2> <name3>value3</name3> </JMSMap>
When reconnecting back to the JMS provider, the JMS transport will spawn multiple threads and once connected the additional threads will get closed. Hence, you will see below log for a particular service multiple times.
"INFO - ServiceTaskManager Reconnection attempt: N for service:Y was successful!"