16
Mule Integration Workshop JMS Rajarajan Sadhasivam

Mule jms

Embed Size (px)

Citation preview

Page 1: Mule   jms

Mule Integration Workshop JMS

Rajarajan Sadhasivam

Page 2: Mule   jms

• Rapidly connect any application, anywhere• Anypoint Platform helps companies prepare for the future with a next-generation SOA platform that connects on-premises systems and the cloud.

• Mule ESB, CloudHub, Mule Studio, Mule Enterprise Management, Anypoint Connectors

Anypoint Platform for SOA

• Connect SaaS with any application, anywhere• Anypoint Platform helps companies connect SaaS applications to each other and the enterprise, in the cloud and on-premises.

• CloudHub, Mule ESB, Mule Studio, CloudHub Insight, Anypoint Connectors

Anypoint Platform for SaaS

• All you need to connect any app, any device and any API• With the Anypoint Platform for APIs, you can build new APIs, design new interfaces for existing APIs and more efficiently manage all your APIs using a single platform.

• API Portal, API Manager, Mule Studio, Mule ESB, CloudHub

Anypoint Platform for API

2

MuleSoft Anypoint Platforms

Page 3: Mule   jms

Chapters Schedule

Filter Types

JMS - Introduction

JMS Queues

JMS Topics

JMS Transport Configuration

JMS Selectors

JMS Transformers

JMS Back Channel

Request Reply

JMS Single Resource Transactions

Page 4: Mule   jms

JMS - Introduction The Java Message Service (JMS) specification is a standard for

messaging middleware (sometimes called ‘Enterprise messaging’). It allows data and events to be exchanged between different

applications by utilizing queues in a centrally located server. This leads to the creation of message-based applications rather than autonomous silos. Messages sent to, or received from, a JMS server are asynchronous which means that the server itself is loosely coupled to application.

Messages can also be transacted to preserve the integrity of the participants’ state.

Vendors supply JMS servers: Apache ActiveMQ, IBM WebSphere MQ, Oracle Weblogic. Each vendor may implement one, or both, of the main versions of the standard – JMS 1.1 or JMS 1.0.2b.

Messages can be placed on one of two different types of message channels within a JMS server – queues or topics.

Page 5: Mule   jms

JMS Queues

JMS Queues JMS queues are nothing more than standard queues implemented within

a JMS server. An application that places items on to a JMS queue makes its messages available to other applications that can read from this queue.

Multiple producers can write to the same queue, and multiple consumers can read from the same queue.

A message is delivered from one producer to one consumer, hence JMS queues are point-to-point.

Page 6: Mule   jms

JMS TopicsJMS Topics Topics differ from queues since they work on a publish/subscribe

mechanism which means that any application wanting to read from the topic must subscribe to it first.

Can have multiple subscribers on a single topic, meaning that when a new message is placed on the topic, all subscribers receive a copy.

Depending on how the subscription is configured, a subscriber may or may not receive notification of items that were published when the subscriber was unavailable. This mechanism is very similar to RSS feeds; multiple users can subscribe to the same feed and receive notification of new items even if they were offline at the time of publication.

Page 7: Mule   jms

JMS Transport ConfigurationJMS Transport Configuration The JMS transport can read and write to any JMS server that is 1.0.2b

compliant or 1.1 compliant. Although the JMS specification is a standard, different servers implement the specifications in different ways so expect to find dedicated configurations in place. These settings may conflict, so for instance; a properly configured MQ Series connector may not necessarily work with an ActiveMQ broker.

Need to configure separate Mule connectors to handle queues and topics if the server is JMS 1.0.2b compliant, because of a restriction in the JMS API; JMS 1.1 servers can use a single connector for either type of destination.

Schema definition

Eg:

<xmlns:jms="http://www.mulesoft.org/schema/mule/jms"

xsi:schemaLocation="http://www.mulesoft.org/schema/mule/jms

http://www.mulesoft.org/schema/mule/jms/3.2/mule-jms.xsd">

Page 8: Mule   jms

JMS Transport Configuration (Contd)

clientId – uniquely identifies the client and must be set if using durable subscriptions for topics. The JMS provider will set it for you automatically to mule.<connector name>.<topic name> but some JMS servers expect you to set it directly. If the clientID is not unique, an invalidClientIDException is thrown.

durable – if a client wishes to receive all messages posted on a topic, even ones that were published when the subscriber is inactive, it needs a durable subscription. This can be overridden on an endpoint.

username – the username for connecting to a JMS server. Can be set on the endpoint.

password – the password for connecting to a JMS server. Can be set on the endpoint.

specification – indicates whether this is a 1.0.2b or a 1.1 server.

Additionally the connectors for specific JMS servers may have attributes of their own. For instance; the ActiveMQ connector uses a brokerURL attribute, which is set to the URL that the JMS server is listening to.

Eg: 1)<jms:activemq-connector name="jmsConnector“ specification="1.1" brokerURL="vm://localhost" />

Page 9: Mule   jms

JMS SelectorsEg: 2)<jms:inbound-endpoint queue="myQueue" />

<jms:inbound-endpoint topic="myTopic" />

<inbound-endpoint address="jms://name:password@topic:myTopic" />

The first JMS inbound endpoint refers to a queue, while the second refers to a topic. The ‘queue’ and ‘topic’ attributes are mutually exclusive as you can either refer to a queue or to a topic but not both. The third endpoint is a generic inbound endpoint that shows how to embed user credentials into the endpoint URI. Note that the topic in use is prefixed with the keyword ‘topic:’; queues do not need to be prefixed.

JMS Selectors

JMS Selectors are JMS specific filters. They differ from Mule filters in one way. When a Mule filter is used, the message is first de-queued from the JMS queue, and then filtered. If the message does not match the filter, it’s discarded.

With a JMS selector, the filter is applied to the message before it is de-queued, hence if the message does not match the filter, it will not be removed from the queue and discarded, but will remain on the queue to be collected by other clients with a matching JMS selector.

Eg: <jms:inbound-endpoint queue="myQueue">

<jms:selector expression="JMSPriority=9" />

</jms:inbound-endpoint>

Page 10: Mule   jms

JMS TransformersJMS Transformers

<jms:jmsmessage-object-to-transformer/>

<jms:object-to-jmsmessage-transformer/>

The JMS message to object transformer converts ‘javax.jms.Message’ objects, or sub-types, to generic Java objects.

can change the ‘returnType’ attribute for this transformer to further typecast the result as follows: javax.jms.TextMessage converts to a java.lang.String. javax.jms.ObjectMessage converts to a java.lang.Object. javax.jms.BytesMessage – converts to a byte array. If the payload is

compressed, it automatically uncompresses it. javax.jms.MapMessage – converts to a java.util.Map. javax.jms.StreamMessage – converts to a java.util.Vector of objects from the

Stream.

Page 11: Mule   jms

JMS Back Channel The object to JMS message transformer does the opposite. And its returnType can

also be tweaked to typecast the JMS message: java.lang.String converts to a javax.jms.TextMessage. java.lang.Object converts to a javax.jms.ObjectMessage. byte[] converts to javax.jms.BytesMessage. java.util.Map converts to a javax.jms.MapMessage. java.io.InputStream converts to a javax.jms.StreamMessage.

JMS Back Channel A single JMS queue alone does not support the notion of back channels. Since queues

are unidirectional (point to point), if a client sends a message on the queue, a reply cannot be read from the same queue. The back channel in JMS is implemented by utilizing two queues, one queue used by the client to send data to the consumer, and the other queue used to write the response message.

Since the second queue is not agreed upon before the actual communication happens, the client can specify on which queue the response should be sent by setting the JMSReplyTo property on the JMS Message.

Page 12: Mule   jms

JMS Back Channel (Contd) In situations where a synchronous connection is configured and the JMSReplyTo property

is not set, the server will not be able to return a result.

To counter this disadvantage, Mule will automatically open a temporary queue for the server to submit the reply message on the newly created queue. If this behavior is not intended, or in some cases not supported by the JMS broker, it can be disabled by setting the disableTemporaryReplyToDestinations on the JMS connector to true. <message-properties-transformer name="addReplyTo">

<add-message-property key="JMSReplyTo" value="reply-queue-2"/>

</message-properties-transformer>

The code snippet illustrates how to use the message properties transformer to set the JMSReplyTo property. Setting the JMSReplyTo property on the Mule message forces Mule to propagate this property to the JMS Message object before message transfer occurs. Instead of using the JMS specific JMSReplyTo property, the more generic ‘MULE_REPLYTO’ could be used. This is then mapped to the appropriate transport specific header depending on the transport being used.

Note: when setting the JMSReplyTo property using the message properties transformer, need to confirm that the value of the property does not include ‘jms://’, but only the name of the queue.

Page 13: Mule   jms

Request Reply The ‘request-reply’ element is very useful when it is required to combine synchronous and

asynchronous flows.

It allows the delivery of a message on the configured outbound endpoint, setting up the necessary properties such as the MULE_REPLY_TO, CORRELATION_ID … and afterwards starts listening on the reply queue automatically for the response message.

Once the response message is delivered, the flow continues processing. <flow name="RequestReplyFlow">

<vm:inbound-endpoint path="RequestReplyRequest"/>

<request-reply timeout="5000">

<jms:outbound-endpoint path="RequestReplyAsyncRequest"/>

<jms:inbound-endpoint path="RequestReplyAsyncResponse"/>

</request-reply>

</flow >

Notice that we don’t need to state the inbound endpoint to route the asynchronous reply to; Mule automatically sets the ‘ReplyTo’ property of each request leaving ‘RequestReplyAsyncRequest’ for ‘RequestReplyAsyncResponse’. In addition, note the ‘timeout’ attribute, which is responsible of setting the time for how long the Request Reply Message Processor will wait for the reply before giving up. Unfortunately, out-of-the-box ‘request-reply’ does not allow more than one outbound endpoint to be used.

Page 14: Mule   jms

JMS Single Resource Transactions Transactions are used with JMS so as not to lose any messages in exceptional situations.

A transaction is started on the inbound endpoint, thus the reading of a message from a queue is done in a transaction. This is configured using the jms:transaction and setting the action to ALWAYS_BEGIN.

Any outbound endpoints writing to a JMS queue would then be configured with a jms:transaction with the action ALWAYS_JOIN, thus the writing to the queue is made part of the same transaction. In this way, the reading from the queue and writing to a queue are both part of the same transaction.

When a transaction is rolled back, any consumed messages are placed back onto the queue and written messages are removed from the queues.

The rolled back message is eventually re-delivered to a service consuming from the queue. If this message always forces an exception to be thrown, thereby forcing a roll back, we need to stop the message being rolled back after a certain number of tries. Such messages are called ‘Poison’ messages and are controlled by configuring the ‘maxRedelivery’ on the JMS connector. By default, the ‘maxRedelivery’ is set to ‘0’.

Page 15: Mule   jms

JMS Single Resource Transactions (Contd)<jms:activemq-connector name="jmsConnector" specification="1.1" brokerURL="vm://localhost" maxRedelivery="3">

</jms:activemq-connector>

<flow name="JmsSimpleTransaction">

<jms:inbound-endpoint queue="requestQueue">

<jms:transaction action="ALWAYS_BEGIN" />

</jms:inbound-endpoint>

<component class="com.mulesoft.MyCustomComponent" />

<jms:outbound-endpoint queue="resultQueue">

<jms:transaction action="ALWAYS_JOIN" />

</jms:outbound-endpoint>

</flow>

In this configuration we have the ‘activemq-connector’ set to redeliver messages a maximum of 3 times. Once this value is exceeded, depending on the Message Broker configuration, these messages will typically be placed on a Dead-Letter-Queue (DLQ).

In this example we start a transaction by reading a message off of the requestQueue, doing some processing in our custom component, and finally put the result on the resultQueue. With these transactions in place, we ensure that for every message placed on the requestQueue, there is a result on the resultQueue or in the case of the message being redelivered 3 times already, the message is placed on the DLQ.

Page 16: Mule   jms

Thank you