Yesterday I was chatting with one of my ex-colleague Shruti and she requested me to write a post on Store-and-Forward (SAF) as the she was having some issue in configuring it and as usual the edocs are pretty confusing to do anything. So I took out sometime and wrote this post which would help others too. For demo check out this post JMS Demo using Weblogic Store-and-Forward (SAF)
First of all lets understand what is Store-and-Forward (SAF) and then will look into how it works, how to configure it with its advantages.
What is Store-and-Forward (SAF)
Store-and-Forward (SAF) is a service which enables weblogic server to deliver messages reliably that is weblogic server make sure that the messages are been delivered between applications that are distributed across weblogic server instances.
How does Store-and-Forward (SAF) works
As the name suggests the messages gets stored at the Sender side in the persistence store and then are forwarded to the Receiver side using the SAF Agent.
Advantages of Store-and-Forward (SAF)
The main reason or the biggest advantage of Store-and-Forward (SAF) for which weblogic server had implemented was that they wanted the messages to be delivered to the receiver even when the receiver was down when the messages where sent.
Steps to Configure Store-and-Forward (SAF)
1. You have to follow steps from Step-1 to Step-5 from the post Basic JMS Demo using WebLogic Queue for Domain-2 running on port 8001 and again same steps BUT this time only follow steps from Step-1 to Step-4 on Domain-1 running on port 7001.
2. Now after doing the above step creating a SAF Agent
3. Create Sub Deployment for SAF in the same Module
4. Creating Remote SAF Context in the same Module
5. Creating SAF Imported Destination in the same Module
6. Creating SAF Imported Destination Queue
Following are the XML configuration which would look like from the SAF point of view
In config.xml file
<sub-deployment> <name>Sub_SAF</name> <target>MySAFAgent</target> </sub-deployment> <descriptor-file-name>jms/mysystemmodule-jms.xml</descriptor-file-name> </jms-system-resource> <admin-server-name>AdminServer</admin-server-name> <saf-agent> <name>MySAFAgent</name> <target>AdminServer</target> <store>FileStore</store> <service-type>Both</service-type> </saf-agent>
In mysystemmodule-jms.xml file
<saf-imported-destinations name="SAFImportedDestinations"> <sub-deployment-name>Sub_SAF</sub-deployment-name> <saf-queue name="MySAFQueue"> <remote-jndi-name>TestQ</remote-jndi-name> <local-jndi-name>Local</local-jndi-name> <non-persistent-qos>At-Least-Once</non-persistent-qos> <time-to-live-default>0</time-to-live-default> <use-saf-time-to-live-default>false</use-saf-time-to-live-default> <unit-of-order-routing>Hash</unit-of-order-routing> </saf-queue> <jndi-prefix>SAF_</jndi-prefix> <saf-remote-context>MyRemoteSAFContext</saf-remote-context> <saf-error-handling xsi:nil="true"></saf-error-handling> <time-to-live-default>0</time-to-live-default> <use-saf-time-to-live-default>false</use-saf-time-to-live-default> </saf-imported-destinations> <saf-remote-context name="MyRemoteSAFContext"> <saf-login-context> <loginURL>t3://localhost:8001</loginURL> <username>weblogic</username> <password-encrypted>{3DES}zMJAPP2UbO1mNu9+Zx7/DA==</password-encrypted> </saf-login-context> </saf-remote-context>
Yup its little bit confusing but that’s it, your configuration for Store-and-Forward (SAF) has been finished. Hope this would help.
Regards,
Ravish Mody
January 26th, 2011 on 7:19 am
Hi!!
This is very useful!!!!!!!!!
But I wasn’t able to fully try it.
How do I use SAF with the Queue Send and Queue Receive?
Thank you!!
January 26th, 2011 on 10:29 am
Hi Jerczey,
You can go through the below post which would help you step by step to use the Queue Send and Queue Receive with SAF.
Topic: JMS Demo using Weblogic Store-and-Forward (SAF)
April 3rd, 2012 on 9:45 pm
Hi Admins,
we have configured our SAF and it seems to work ok in a couple of environments without any issue. On a new environment (exact replica of the other two) however, it doesn’t work and we get the error below when we start up the managed server. It seems as though it is happening during the initialisation of the Remote context.
The queue is present on the remote server and the JNDI Name on both are the same. I can telnet to the remote server without any issues and can see the connections on the remote server using netstat. I have created a new user on the remote servers (added it to the Operators group) and used the credentials in the Remote context but still no dice. I really don’t have any idea why this error is happenng in this particular environment. To make matters a bit more confusing, I get a slightly different error the second time I restart the server without having made any changes (I have posted both errors below – notice the slight change in timestamps). I’m leaning towards some issue on the network but feel I might have missed something. Any help will be appreciated. Thanks in advance.
#### <>
#### <>
#### <> <The JMS SAF forwarder failed to connect to the remote destination "t3://remote_server:8001/the.queue.on.the.remote.server.xml", because of javax.naming.NamingException [Root exception is java.rmi.UnexpectedException: Marshalling: ; nested exception is:
java.rmi.ConnectException: This RJVM has already been shutdown -655181168384673332S:remote_server:[8001,-1,-1,-1,-1,-1,-1]:remote_domain:ms01]
at weblogic.jndi.internal.ExceptionTranslator.toNamingException(ExceptionTranslator.java:86)
at weblogic.jndi.internal.ExceptionTranslator.toNamingException(ExceptionTranslator.java:32)
at weblogic.jndi.WLInitialContextFactoryDelegate.toNamingException(WLInitialContextFactoryDelegate.java:783)
at weblogic.jndi.WLInitialContextFactoryDelegate.pushSubject(WLInitialContextFactoryDelegate.java:680)
at weblogic.jndi.WLInitialContextFactoryDelegate.newContext(WLInitialContextFactoryDelegate.java:468)
at weblogic.jndi.WLInitialContextFactoryDelegate.getInitialContext(WLInitialContextFactoryDelegate.java:375)
at weblogic.jndi.Environment.getContext(Environment.java:315)
at weblogic.jndi.Environment.getContext(Environment.java:285)
at weblogic.jndi.Environment.createInitialContext(Environment.java:208)
at weblogic.jndi.Environment.getInitialContext(Environment.java:192)
at weblogic.jndi.Environment.getInitialContext(Environment.java:170)
at weblogic.jndi.Environment.getContext(Environment.java:215)
at weblogic.jms.forwarder.Forwarder.getInitialContext(Forwarder.java:387)
at weblogic.jms.forwarder.Forwarder.connectTarget(Forwarder.java:405)
at weblogic.jms.forwarder.Forwarder.reconnect(Forwarder.java:246)
at weblogic.jms.forwarder.Forwarder.timerExpired(Forwarder.java:305)
at weblogic.timers.internal.TimerImpl.run(TimerImpl.java:273)
at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:516)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
Caused by: java.rmi.UnexpectedException: Marshalling: ; nested exception is:
java.rmi.ConnectException: This RJVM has already been shutdown -655181168384673332S:remote_server:[8001,-1,-1,-1,-1,-1,-1]:remote_domain:ms01
at weblogic.common.internal.BootServicesStub.authenticate(BootServicesStub.java:57)
at weblogic.security.acl.internal.RemoteAuthenticate.authenticate(RemoteAuthenticate.java:90)
at weblogic.jndi.WLInitialContextFactoryDelegate.authenticateRemotely(WLInitialContextFactoryDelegate.java:742)
at weblogic.jndi.WLInitialContextFactoryDelegate.pushSubject(WLInitialContextFactoryDelegate.java:674)
… 16 more
Caused by: java.rmi.ConnectException: This RJVM has already been shutdown -655181168384673332S:remote_server:[8001,-1,-1,-1,-1,-1,-1]:remote_domain:ms01
at weblogic.rjvm.RJVMImpl.getOutputStream(RJVMImpl.java:343)
at weblogic.rjvm.RJVMImpl.getRequestStreamForDefaultUser(RJVMImpl.java:686)
at weblogic.common.internal.BootServicesStub.authenticate(BootServicesStub.java:50)
… 19 more
Slightly different error after another restart (with no further config changes)
#### <>
#### <>