Tuesday, November 10, 2009

Set up a Weblogic Server 11g (10.3.1) JMS Store and Forward demo

Weblogic Server (supported from 9.x) contains JMS Store-and-Forward (JMS SAF) functionality. Basically this functionality makes it possible to receive messages on a specific server instance (proxy), forward the messages to different Weblogic server instances and process them on those 'hidden' instances or forward them again...In case the processing server is unavailable the message will be automatically redelivered when the server is available again..You can think about many use cases in which JMS SAF can be very useful. For example, in the situation in which you don't want to stop the message communication when an update of 'processing logic/functionality is needed, JMS SAF can increase the high-availability of your messaging solution. Also it can be used to off-load complex message processing to dedicated servers.

In this posting I will describe how you can set up JMS SAF using Weblogic Server 11g (10.3.1) with a domain configuration consisting out of 1 AdminServer and 2 non-clustered Managed Servers serve in the roles of sender (or actually the forwarder) and receiver.

I skip the domain set up and assume you are familiar with it. To define the JMS SAF resources the best thing to do is to follow the steps that are described Oracle Fusion Middleware 11g SAF guide. I will a not repeat them in this blog.. In its place, I will give additional explanation about specific configuration steps and things you have to do but which are not covered completely in the guide.

Receiving Side - Extra
  • Create a JMS Server
  • Create a Subdeployment in the receiving JMS module and target it to the JMS Server
  • Create a destination queue and remember the JNDI name that you choose. We need it when the sending side will be configured. Target the queue to the JMS module's Subdeployment
  • Create also Connection factory at the receiving side (At least I did it. However, you could try not to create a connection factory, because the sending side never uses it..). In the picture below you can see the configuration of the JMS resources at the receiving side that I have used in my demo:



Sending Side - Extra
  • Create a JMS Connection Factory in the sender JMS module. Use the default settings and and choose a easy-to-remember JNDI name. We need it in the Java client to test the JMS SAF configuration.

Sending Side - Additional notes
- I simply used the default settings for
  • the persistent store of the SAF agent
  • targeting and subdeployment
  • the type of error handling (log). If you decide to use an Error destination, make sure that the queue is targeted to same JMS server/Subdeployment as used for the SAF queue. Most probably, this will mean that you have to create a Subdeployment instead of using the default as I did :)
- For the SAF queue you have to use the JNDI name that you have chosen during the configuration of the destination queue at the receiving side for the remote JNDI location. For simplicity, you can use the same for the local JNDI name
- The JNDI name of the SAF Remote Destination will serve as the prefix of the local JNDI name that you defined for your SAF queue. Keep that in mind when you try to connect to the SAF remote queue (see further on in this posting for in the Java example)


Here's the overview of the JMS SAF resources in the JMS module, which is targeted to the sending server, that I have used in my demo set up:




JMS SAF remote Java client
Now that we have finished the Weblogic Server 11g JMS SAF configuration, we can test it by using a simple Java client. The code fragment below shows the code that you can use to test your configuration. Please note:

  • Import the J2EE 1.5 and Weblogic Remote client libraries in JDeveloper 11g
  • If you are not sure about the exact JNDI binding names for the Connection Factory and JMS destination, you can browse the JNDI tree of the sending server (Admin Console -> Environment -> servers -> -> Configuration/General tab)
  • You can either use '.' or '/' as the separator in your JNDI name


String CFName = "jms/ConnectionFactorySending";
String destName = "jmssaf.RemoteDestjms.Queue_Receiving";

Connection conn = null;
Session session = null;
MessageProducer prod = null;
try{
//Set the Initial Context properties
Properties env = new Properties( );
env.put(Context.SECURITY_PRINCIPAL, "weblogic");
env.put(Context.SECURITY_CREDENTIALS, "welcome1");
env.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL,
"t3://localhost:7004");

InitialContext context = new InitialContext(env);

//Lookup connection factory
QueueConnectionFactory queueConnectionFactory =
(QueueConnectionFactory) context.lookup(CFName);

//Create a connection and session
conn = queueConnectionFactory.createConnection();
session = conn.createSession(false, 0);

//Lookup queue
Queue q = (Queue) context.lookup(destName);

//Send message
prod = session.createProducer(q);
TextMessage msg = session.createTextMessage();
msg.setJMSMessageID(Guid.newInstance().toString());
msg.setText("SAF Test message");
prod.send(msg);

}
catch(NamingException ne){
System.out.println("NamingException: "+ne.toString());
}
catch(JMSException jmse){
System.out.println("NamingException: "+jmse.toString());
}
finally{
try{
prod.close();
session.close();
conn.close();
}
catch(Exception e){
System.out.println("Excepion in finally branch: "+e.toString());
}
}


Run your program to send a message to the sending server. Before you do this make sure the receiving server is not running to check if SAF is working as expected. When the message is submitted, check the Monitoring tab in the Sending SAF agent configuration screen to check if the message is stored and waits for redelivery (from here you are able to perform more management tasks, like pausing forwarding etc.). When you start the receiving server the message will be redelivered automatically to the receiving server..

This blog serves as a starting point for using JMS SAF. More info about all the specific configuration options and monitoring/management options can be found here.

5 comments:

Marc Kelderman SOA Blog said...

Tom,

Can you add the import statements in the source code?

Anonymous said...

Can we use jdeveloper to connect to the SAF queue

Tani said...

Here you have done a good work to describe how one can set up JMS SAF using Weblogic Server 11g (10.3.1) with a domain configuration consisting out of 1 AdminServer and 2 non-clustered Managed Servers serve in the roles of sender (or actually the forwarder) and receiver.

sap erp system

hallsarah204@gmail.com said...

This is a very detailed description; I wonder if we can use java developer to connect to the SAF queue? ​Thanks for the provided information! P.S. Buy any academic paper including an elementary essay or a lengthy dissertation here by following http://dissertationwriting.services/.

Anonymous said...

I have using your provided code to send massage to my domain1 to domain2 and its successfully work, but when I put in the massage in JMSModel local queue domain1, it not reflect to Remote Queue in Domain2.

For me a SAF agent is used to transfer a message from one JMS queue to another across the Domains or even within domains. Why was there a need to write the code to send a message to a queue. Each SAF has a local queue JNDI and Remote queue jndi and triggers the message from source to destination as soon the message arrives.