Saturday, October 31, 2015

SpringJMS - Step by Step Guide to create Consumer (Super Simple)

Step 1 - You will need same Jar files which we discussed in Producer Example

Spring Core
Spring Context
Spring JMS
activemq-all
commons-logging
slf4j

Step 2: Create applicationContext.xml in classpath

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jms="http://www.springframework.org/schema/jms"
       xmlns:amq="http://activemq.apache.org/schema/core"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context 
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/jms 
                           http://www.springframework.org/schema/jms/spring-jms.xsd
                           http://activemq.apache.org/schema/core 
                           http://activemq.apache.org/schema/core/activemq-core.xsd">
<context:component-scan base-package="com.itech" />
<context:annotation-config/>
<!-- JMS ConnectionFactory to use, configuring the embedded broker using XML -->
<bean id="activemqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <!-- brokerURL, You may have different IP or port -->
    <constructor-arg name="brokerURL" value="vm://localhost:61616" />
  </bean>  
<!-- Pooled Spring connection factory -->
 <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
    <constructor-arg ref="activemqConnectionFactory" />
 </bean>
<!--  Queue Destination  -->
    <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
    <!-- name of the queue -->
    <constructor-arg index="0" value="THIS.IS.TEST.QUEUE" />
  </bean>
 
  <!-- Listeners   -->
<jms:listener-container connection-factory="connectionFactory"> 
               <jms:listener destination="THIS.IS.TEST.QUEUE" ref="messageListenerTest" /> 
 </jms:listener-container>


</beans>


Step 3:

You need a Consumer Class which implements MessageListener interface:

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import org.springframework.stereotype.Component;

@Component("messageListenerTest")
public class MessageListenerTest implements MessageListener {

@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println(textMessage.getText());
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

That's it, Now try sending a message with Producer example, and message will be listened by this MessageListener implementation. 

Thursday, October 29, 2015

Super Simple Example of Spring JMS - Producer

Step 1: You need Jar files:

A. Spring core, spring-context
B. Spring JMS
C. activemq-all 
D. slf4j , log4j etc.


Step 2: Create a Java Project in Eclipse and add "applicationContext.xml" File directly under "src" folder:

applicationContext.xml :

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jms="http://www.springframework.org/schema/jms"
       xmlns:amq="http://activemq.apache.org/schema/core"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context 
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/jms 
                           http://www.springframework.org/schema/jms/spring-jms.xsd
                           http://activemq.apache.org/schema/core 
                           http://activemq.apache.org/schema/core/activemq-core.xsd">

<context:component-scan base-package="com.itech" />
<context:annotation-config/>

<!-- JMS ConnectionFactory to use, configuring the embedded broker using XML -->
<bean id="activemqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <!-- brokerURL, You may have different IP or port -->
    <constructor-arg name="brokerURL" value="vm://localhost:61616" />
  </bean>  

<!-- Pooled Spring connection factory -->
 <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
    <constructor-arg ref="activemqConnectionFactory" />
 </bean>

<!--  Queue Destination  -->
    <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
    <!-- name of the queue -->
    <constructor-arg index="0" value="THIS.IS.TEST.QUEUE" />
  </bean>

  <!-- JmsTemplate Definition -->
  <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="defaultDestination" ref="queueDestination" />
  </bean>

</beans>


Have a look at XML, it has almost everything you need to start with: - ConnectionFactory, Destination and Spring Provides JmsTemplate which we will be using to send the message.

Step 3: Create Test Class:

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

public class ProducerTest {

public static void main(String[] args) {
// Load Application Context 
   ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  
            // Get JmsTemplate Bean from context     
   JmsTemplate template = (JmsTemplate) ctx.getBean("jmsTemplate");
 
           // Create Message 
   MessageCreator message = new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("This is test message");
}
};

              // Send the message
template.send(message);

              // Close the context
((ClassPathXmlApplicationContext)ctx).close();
// You are Done!!
}

}

That's it. You are Done! You have written  a complete code in SpringJMS for sending a message.
Thanks!




MDB (Message Driven Beans) Vs. SpringJMS - Point by Point Comparison

EJB’s Message Driven Beans (MDB) Vs. SpringJMS
MDB and SpringJMS can be compared with multiple features:

1.       Learning Curve

Most important feature of SpringJMS is, object can be easily configured in XML format making is extra easy to manage.  Some features like concurrentConsumer can be managed with XML without touching Java code.

MDB on the other hand involves expert level understanding of EJB and has more LOC to write for same operation.  So Overall learning Curve for SpringJMS is less.

2.       Development Time
Spring implementation uses the JmsTemplate helper class to simplify working with the JMS API to send the message. Also, auto starting consumers with application context and ease of handling properties with xml configuration, reduces development time, in turn production cost of application.
MDB though robust, needs good amount of efforts in comparison.

3.       Container Dependency
MDB requires EJB container. Container is mainly responsible for instantiation and handling other life cycle events for MDB. EJB 3.0 also has additional packaging and deployment requirements that
Spring does not. Also message listeners must be EJB components.

Spring is container of its own. SpringJMS do not require any external container to execute. Any POJO can potentially be activated in response to incoming messages

4.       Multi-Queue Configuration:
MDBs are static for one queue. One MDB cannot be used for consuming from two or multiple queues. On the contrary, Spring provides the flexibility to customize the number of queues to listen to and dynamically configure the destinations as well.

5.       Security
For MDB, security is managed by the EJB container by configuring a security identity for the MBM

Spring UserCredentialsConnectionFactoryAdapter provides a mechanism to specify user credentials for every JMS connection to secure the JMS connection.

6.       Dependency management/configurability/intermediation
Spring offers much more mature and configurable support for dependency management than EJB 3.0 with its dependency injection and IOC framework

7.       Availability
The Enterprise server controls JMS connection pooling and failover and reconnecting to the message broker when the connection is lost has to be supported and configured at the enterprise server level .

Individual applications and modules cannot control or override JMS availability
Spring DMLC automatically re-establishes connections if the message broker becomes unavailable

8.       Performance

The EJB MDB container manages the JMS Connection Pool and needs to be configured to optimize the concurrent processing of messages

Spring DMLC allows you to scale the number message consumers using the concurrentConsumers property and the maxConcurrentConsumers property. It provides various levels of caching of the JMS resources (connections and sessions) and JMS consumers for increased performance

9.       Transaction

Can use the default container managed transaction to allow the EJB container to handle transaction demarcation or specify local transactions to group message sends and receives

Spring DMLC provides support for local JMS transactions as well as an external transaction manager around message reception and listener execution

10.   Message Convertors

Spring provides message converters which can automate the conversion of Java objects to message content

MDB provides no such features.

11.   Future Orientation

Spring has vibrant open source community and considered as very stable but futuristic design. Many newer MOMs and EIPs (Enterprise Integration Pattern) like Camel directly uses Spring for messaging implementation.

EJBs on the contrary and seen lesser in market.

Summary:

                Considering current era of IT development, adopting SpringJMS over MDB is always a better choice. 

Tuesday, August 6, 2013

Using MQXAQueueConnectionFactory in Tomcat





Using Atomikos / XA transaction with your connection is not a bad idea sometimes. Below Connection Factory resource will give a nice idea about tomcat JNDI entry for
MQXAQueueConnectionFactory.
 




<Resource
                name="jms/MQCF"
                auth="Container"
                type="com.atomikos.jms.AtomikosConnectionFactoryBean"
                factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory"
                uniqueResourceName="MQPutQCFXA_MQSeries_XA_RMI"
                xaConnectionFactoryClassName="com.ibm.mq.jms.MQXAQueueConnectionFactory"
                xaProperties.hostName="YOUR_HOST"
                xaProperties.port="XXXX"
                xaProperties.channel=" CHANNEL "
                xaProperties.queueManager=" YOUR _QMGR"
                maxPoolSize="3"
                minPoolSize="1" />


I see a common exception while connecting with XA Connection factory:

Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2495;AMQ8568: The native JNI library 'mqjbnd' was not found. [3=mqjbnd]
    at com.ibm.mq.jmqi.local.LocalMQ$1.run(LocalMQ.java:252)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.ibm.mq.jmqi.local.LocalMQ.initialise_inner(LocalMQ.java:216)


This occurs when you are trying to connect to local binding. You can change that to client connection by making transport type as ‘1’.

xaProperties.transportType="1"

Just adding this property in Resource entry should resolve the issue. Please post questions if any.
I will add ActiveMQ XA Connection factory example soon.

Friday, October 12, 2012

ActiveMQ Composite Destinations


ActiveMQ Composite Destinations

Composite queue allows one-to-many relationship. Send a message to One Queue (A) and it will forward the message to Queue B, Queue C and Topic D.
To map Composite destination you need to add following section in virtualDestinations tag.
 <destinationInterceptors>
    <virtualDestinationInterceptor>
        <virtualDestinations>
<compositeQueue name="TEST.QUEUE.A">
   <forwardTo>
<queue physicalName="TEST.QUEUE.B" />
<queue physicalName="TEST.QUEUE.C" />
<queue physicalName="TEST.TOPIC.D" />
   </forwardTo>
</compositeQueue>
        </virtualDestinations>
    </virtualDestinationInterceptor>
  </destinationInterceptors>

By default, subscribers cannot consume messages directly from a composite queue or topic - it is a logical construct only. Given the configuration above, subscribers can only consume messages from TEST.QUEUE.B, TEST.QUEUE.C and TEST.TOPIC.D; but NOT TEST.QUEUE.A.

Using filtered destinations

You may wish to create a virtual destination which forwards messages to multiple destinations but applying a selector first to decide if the message really does have to go to a particular destination.
 <destinationInterceptors>
    <virtualDestinationInterceptor>
        <virtualDestinations>
<compositeQueue name="TEST.QUEUE.A">
   <forwardTo>
<filteredDestination selector="criteria = ‘B’” queue="TEST.QUEUE.B" />
<filteredDestination selector="criteria = ‘C’” queue="TEST.QUEUE.C" />
<filteredDestination selector="criteria = ‘D’” queue="TEST.TOPIC.D" />
   </forwardTo>
</compositeQueue>
        </virtualDestinations>
    </virtualDestinationInterceptor>
  </destinationInterceptors>

In the case above, message from TEST.QUEUE.A will be forwarded to filtered destinations with selector criteria. Result is same as having selector based consumer on TEST.QUEUE.B


Important Aspects of Composite Destinations:

-          Listener Queues (under forwardTo Tag) will not be created automatically. If queues are not present, message will be LOST.
-          If you want to store message in composite queue, make forwardOnly flag as ‘false’. It’s true by default.
<compositeQueue name="TEST.QUEUE.A" forwardOnly="false">   
      <forwardTo>
<queue physicalName="TEST.QUEUE.B" />
   </forwardTo>
</compositeQueue>

-          Composite queue can send the message to Virtual Topic, which will be further consumed by multiple Virtual Destinations.
-          Virtual Topic Selector Aware Consumers will not pull the message if consumer is not active; On the contrary, Filtered Composite destinations pull the message despite of consumer’s active status. This is very helpful in real world scenarios.
-          Important: Composite Destinations Supports wildcards. This is also valid for Filtered Destinations.
<destinationInterceptors>
   <virtualDestinationInterceptor>
      <virtualDestinations>
<compositeQueue name="TEST.QUEUE.A">
<forwardTo>
   <filteredDestination selector="criteria = ‘B’” queue="TEST.B.>."/>
   <queue physicalName="COMPOSITE.WILD.>."/>
</forwardTo>
</compositeQueue>
</virtualDestinations>
</virtualDestinationInterceptor>
</destinationInterceptors>

In the settings above, message will be forwarded to all the queues starting with “COMPOSITE.WILD”. Also, the message with filtered destinations will be forwarded to all the queues starting with ‘TEST.B’.

Thursday, August 30, 2012

WTX with ActiveMQ Using JMS Adapter


WebSphere Transformation Extender's interaction with Activemq. Not hard but little tricks are important. As usual, if you google this solution, you will not find a single site or blog stating exact steps. So, here it is. Post your comments for questions.

Step 1: Setting jndi.propertise

Place provided “jndi.properties” file in <WTX_INSTALL>/java/lib directory or defined CLASSPATH. Sample jndi.properties can be downloaded from here.

Step 2: Include Jars

Include following Jars in local accessible folder.
activemq-all-5.5.1-fuse-07-11.jar
geronimo-jms_1.1_spec-1.1.1.jar
log4j-1.2.16.jar
slf4j-api-1.6.4.jar
slf4j-log4j12-1.6.4.jar
spring-jms-3.0.6.RELEASE.jar

Step 3: Add External Jars in dtx.ini


Include above mentioned jars in External jar section dtx.ini file. (replace home/aad/tmp with your folder path from root)
jar1=/home/aad/tmp/activemq-all-5.5.1-fuse-07-11.jar
jar2=/ home / aad /tmp/geronimo-jms_1.1_spec-1.1.1.jar
jar3=/ home / aad /tmp/log4j-1.2.16.jar
jar4=/ home / aad /tmp/slf4j-api-1.6.4.jar
jar5=/ home / aad /tmp/slf4j-log4j12-1.6.4.jar
jar6=/ home / aad /tmp/spring-jms-3.0.6.RELEASE.jar

Step 4: Command

-T -HDR -ICTXFURL tcp://<brokerURL>:<port>
 -ICTXF org.apache.activemq.jndi.ActiveMQInitialContextFactory
-CFN "connectionFactory"
-QN " testQueue"
Where
connectionFactory – JNDI Connection Factory Name
testQueue – JNDI Queue Name

Wednesday, August 8, 2012

WebSphere MQ With Tomcat : JNDI Property Names


WebSphere MQ JNDI Property Names:

I searched across the web and I didn’t find a single site stating exact JNDI MQ option for setting SSLCipherSuite value. I made this entire list of properties which can be useful for providing wide range of options to MQConnectionFactoty.
WebSphere MQ (IBM MQ) has lot of properties which can be made available from JNDI (Context.XML) entries. IBM MQ uses very specific Names which need to be set in Context XML Resource Entry.
Sample Resource Entry in Context is as below:
<Resource
        CHAN="<Channel Name>"
        HOST="<HostName>"
        PORT="<portNumber>"
        QMGR="<queueManagerName>"
        .
        .
        auth="Container"
       description="MQ JMS Queue Connection Factory"
        factory="com.ibm.mq.jms.MQQueueConnectionFactoryFactory"
        name="jms/ConnectionFactory"
        type="com.ibm.mq.jms.MQQueueConnectionFactory"/>

Below is the list of properties and their meaning.
Property Name
Used For
Short Description
CHAN
Channel Name
1 through 20 ASCII characters
HOST
Host Name
A valid TCP/IP host name
PORT
Port Number
A valid TCP/IP port numbe
QMGR
Queue Manager Name
Queue Manager Name
VER
Version
String
DESC
Description
String
TRAN
Transport Type
BINDINGS, CLIENT, DIRECT, QUEUED
CID
Client ID
JMS client identifier
CCS
CCS ID
coded character set identifier
MNS
Map Style Name
String
RCX
Receive Exit
String
RCXI
Receive Exit Init
String
SCX
Security Exit
String
SCXI
Security Exit Init
String
SDX
Send Exit
String
SDXI
Send Exit Init
String
SCPHS
SSL Cipher Suite  value
Cipher suite to use for SSL connection
SPEER
SSL Peer Name
Distinguished name is used to check the identifying certificate presented by the server at connection time
SCRL
SSL Certificate Store
 list of zero or more Certificate Revocation List
HC
HDR Component list
String
MC
Message Comp list
String
CT
Connection Tag
String
CTO
Connection Options
String
SCC
Send Check Count
String
SCALD
Shared Conversation Allowed
String
SRC
SSL Reset Count
String
SFIPS
SSL Fips Required
String
SPAG
Synch Points All Gets
String
UCP
Use Connection Pooling
Optional set of connection pool settings
PINT
Polling Interval
The interval, in milliseconds, between scans of all receivers during asynchronous message delivery
PVER
Provider Version
String
WCFMT
Wild Card Format
String
MBS
Message Batch Size
String
FIQ
Fail If Quiesce
Whether applications return from a method call if the queue manager has entered a controlled failure.
LA
Local Address
Specifies the local server address
RINT
Rescan Interval
the interval in milliseconds between which a topic is scanned to look for messages that have been added to a topic out of order
TCM
Target Client Matching
String
AEX
Asynch Exception
String
CCDTRUL
CCDT URL
String

These properties are very useful while using websphere MQ with Tomcat. This will enable user to get rid of provider specific code in App.
This list doesn’t end here. I will add more properties, as and when I get to know them, I will also add the descriptions as I find them.
More questions? Post a comment. I will try to answer as soon as possible.