To configure a Messaging Bridge you can follow the steps provided in the post Steps to Configure Store-and-Forward (SAF) on Weblogic Server
In this post I would be using a stand-alone java code for producing messages as a Producer/Clint and for consuming the messages as a Consumer/Listener. By which we can make sure that if something goes wrong then we can narrow down the issue if its an issue with WLS or the code, asmany times their an issue with the Producer or a Consumers.
.
.
Steps of test the Store-and-Forward (SAF)
- Create a Directory somewhere in your file system like: “D:OracleJMSQueue” to write the QueueSend.java and QueueReceive.java programs.
- In QueueSend.java copy the below commandNote: Here we are giving the Queue JNDI as “SAF_Local” because “SAF_” was the prefix for SAF Imported Destination and “Local” was the local JNDI name for the SAF Imported Destination Queue, hence in the below JDNI tree shows the “SAF_Local”
import java.io.*; import java.util.Hashtable; import javax.jms.JMSException; import javax.jms.Queue; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; import javax.jms.QueueSender; import javax.jms.QueueSession; import javax.jms.Session; import javax.jms.TextMessage; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; public class QueueSend { public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory"; // ******* Give the CONNECTION FACTORY JNDI name which is QCF ******** public final static String JMS_FACTORY="QCF"; // ******* Give the UNIFORM DISTRIBUTED QUEUE JNDI name which is SAF_Local ******** public final static String QUEUE="SAF_Local"; private QueueConnectionFactory qconFactory; private QueueConnection qcon; private QueueSession qsession; private QueueSender qsender; private Queue queue; private TextMessage msg; public void init(Context ctx, String queueName) throws NamingException, JMSException { qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY); qcon = qconFactory.createQueueConnection(); qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); queue = (Queue) ctx.lookup(queueName); qsender = qsession.createSender(queue); msg = qsession.createTextMessage(); qcon.start(); } public void send(String message) throws JMSException { msg.setText(message); qsender.send(msg); } public void close() throws JMSException { qsender.close(); qsession.close(); qcon.close(); } public static void main(String[] args) throws Exception { if (args.length != 1) { System.out.println("Usage: java QueueSend WebLogicURL"); return; } InitialContext ic = getInitialContext(args[0]); QueueSend qs = new QueueSend(); qs.init(ic, QUEUE); readAndSend(qs); qs.close(); } private static void readAndSend(QueueSend qs) throws IOException, JMSException { String line="Test Message Body with counter = "; BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); boolean readFlag=true; System.out.println("ntStart Sending Messages (Enter QUIT to Stop):n"); while(readFlag) { System.out.print("<Msg_Sender> "); String msg=br.readLine(); if(msg.equals("QUIT") || msg.equals("quit")) { qs.send(msg); System.exit(0); } qs.send(msg); System.out.println(); } br.close(); } private static InitialContext getInitialContext(String url) throws NamingException { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY); env.put(Context.PROVIDER_URL, url); return new InitialContext(env); } }
- In QueueReceive.java copy the below command
import java.util.Hashtable; import javax.jms.*; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; public class QueueReceive implements MessageListener { public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory"; // ******* Give the CONNECTION FACTORY JNDI name which is QCF ******** public final static String JMS_FACTORY="QCF"; // ******* Give the UNIFORM DISTRIBUTED QUEUE JNDI name which is TestQ ******** public final static String QUEUE="TestQ"; private QueueConnectionFactory qconFactory; private QueueConnection qcon; private QueueSession qsession; private QueueReceiver qreceiver; private Queue queue; private boolean quit = false; public void onMessage(Message msg) { try { String msgText; if (msg instanceof TextMessage) { msgText = ((TextMessage)msg).getText(); } else { msgText = msg.toString(); } System.out.println("nt<Msg_Receiver> "+ msgText ); if (msgText.equalsIgnoreCase("quit")) { synchronized(this) { quit = true; this.notifyAll(); // Notify main thread to quit } } } catch (JMSException jmse) { jmse.printStackTrace(); } } public void init(Context ctx, String queueName) throws NamingException, JMSException { qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY); qcon = qconFactory.createQueueConnection(); qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); queue = (Queue) ctx.lookup(queueName); qreceiver = qsession.createReceiver(queue); qreceiver.setMessageListener(this); qcon.start(); } public void close()throws JMSException { qreceiver.close(); qsession.close(); qcon.close(); } public static void main(String[] args) throws Exception { if (args.length != 1) { System.out.println("Usage: java QueueReceive WebLogicURL"); return; } InitialContext ic = getInitialContext(args[0]); QueueReceive qr = new QueueReceive(); qr.init(ic, QUEUE); System.out.println("JMS Ready To Receive Messages (To quit, send a "quit" message from QueueSender.class)."); // Wait until a "quit" message has been received. synchronized(qr) { while (! qr.quit) { try { qr.wait(); } catch (InterruptedException ie) {} } } qr.close(); } private static InitialContext getInitialContext(String url) throws NamingException { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY); env.put(Context.PROVIDER_URL, url); return new InitialContext(env); } }
- Now open 2 – command promt Windows and run “setWLSEn.cmd” in all the three Command Windows to set the Environment (PATH & CLASSPATH).
- Then compile the QueueSend.java and QueueReceive.java programs.
- Now run the code with the following command
- Once this is been done try to send few messages in the Prompt one which is sending to the port 7001 which the Sender in Domain-1 , if the configuration is fine then you will notice that the message would be received on Prompt-2 which is listening on port 8001 which the Receiver in Domain-2 as shown in the below snap-shot.
Prompt-1
java QueueSend t3://localhost:7001
Prompt-2
java QueueReceive t3://localhost:8001
Note:
With the “java QueueSend” and “java QueueReceive” command you have to give the<Protocol>://<IP-address>:<Port number>of the managed servers in different prompts.
This way we can see that using weblogic Store-and-Forward (SAF) is working fine and can transfer messages from one domain to the second domain easily.
8. However that was just to check if our configuration was correct or not, as its working fine now try to SHUTDOWN Domain-2 which is running on 8001 port and now send few more messages from Prompt-1.
9. Now again START the server for the Domain-2which is running on 8001 port and go to the following path and check if you see the messages which were sent during the Domain-2 was down, has been received as shown in the below snap-shot
Console Path for Domain-2 :
JMS Modules -> MySystemModule -> MyTestQueue -> Monitoring (tab)
Thus now we have tested that even when the Receiver was down still weblogic Store-and-Forward (SAF) was able to send the messages once the receiver came up.
Thanks,
Ravish Mody
February 20th, 2011 on 11:31 pm
Hi Ravish,
1) Can you please point the difference b/w Bridge and SAF
.
2) When should we use SAF and when should we use Bridge?
Thanks
Sumit
April 22nd, 2011 on 10:58 am
Thanks for the excellent demo. There is an error in the Queue send. The string is not correctly closed.
public final static String QUEUE=”SAF_Local;
April 22nd, 2011 on 12:47 pm
Hi Testab,
Thank you for pointing out the string was not correctly closed.
Magic Team Shares Bonus 20 Magic Points with you.
Regards,
Ravish Mody
April 22nd, 2011 on 11:23 am
Hi Sumit, I think the answer to your question is we can ue a bridge between weblogic and thrid party servers such as JBoss, Websphere MQ etc.
We can use SAF only in weblogic source and destinations.
April 22nd, 2011 on 11:25 am
Hi Ravish,
I configured stuff exactly as you mentioned but I do not receive messages on the QueueReceieve
April 22nd, 2011 on 11:26 am
Nevermind restarting the admin servers fixed the issue.
August 16th, 2011 on 11:12 am
Hi Ravish,
Thanks a lot for sharing this article.
I have followed the steps as you have mentioned in the article about how to create a SAF Agent and other related resources.
Can you please guide me how to manually test the SAF Service, in the sense I would like to post one JMS Message onto the respective queue configured for SAF and see if it’s available on the remote destination or not.
Regards,
Milin Jc.
August 16th, 2011 on 11:23 am
Hi Milin Jc,
The above article does the same thing which you are looking out for. It sends a messages to the local destination which is been received from the remote destination which has been configured. Do follow the above steps in which we have given you an example code as well to send and receive the messages.
Regards,
Ravish Mody
August 16th, 2011 on 12:05 pm
Hi Ravish,
I wanted to know if we can explicitly send post a message on a SAF Configured Queues.
Thanks,
Milin Jc.
August 16th, 2011 on 1:24 pm
Hi Milin Jc,
Yes, you can do it.
As shown in the above article in Step-6 I am sending few messages on the local SAF queue which was running on “t3://localhost:7001” as shown in the article http://middlewaremagic.com/weblogic/?p=4854 in the Step-6 last image called “Configuring “Local” JNDI for SAF Imported Destination Queue”.
Where as we are getting the same messages from the remote SAF queue which is running on “t3://localhost:8001” as shown in the article http://middlewaremagic.com/weblogic/?p=4854 in the Step-6 3rd image called “Configuring “Remote” JNDI SAF Imported Destination Queue”. using the “QueueReceive” program.
The result can be seen in the above article’s image in the Step-7, hope this explanation would help you try the same test.
Regards,
Ravish Mody
August 18th, 2011 on 12:29 pm
Hey Ravish,
I understood the Queue configuration which would be imported on SAF Imported Destination under JMS Module.
What I was trying to ask is how we can post a message on SAF Queue through Weblogic portal. In the case of JMS Queue, we can simply go to the ‘Messaging’ page and create New Message/Import Message. This can not be achieved for SAF Queues.
Any solution to post a message on SAF Queue through Weblogic Portal?
Regards,
Milin JC
August 18th, 2011 on 12:50 pm
Hi Milin JC,
No, from Weblogic Console we cannot post messages on the SAF Queue. May I know the reason why are you looking out to put messages from console ? Is there any specific reason for it.
Regards,
Ravish Mody