In WLS 9.0, there was a new proprietary JMS feature that was introduced to WebLogic Server; the Store and Forward Agent. The SAF agent is one that does exactly that – it stores messages (using a file or JDBC persistence Store) and then forwards them to remote WLS domain. Originally, it was added to WLS to allow a server to persist messages locally without the use of a JMS setup. It WLS 9.2, it was expanded to be used as a method for adding persistence to a JMS client.
The Store and Forward Agent is one that is used by both JMS and Web Services; JMS requires a sending agent and WebServices uses both a sending a receiving agent. A SAF sending agent stores the message locally, before forwarding to the remote domain and then retries should there be no response. The receiving agent is one that collects the message and removes duplicates, something that is done within the JMS subsystem, hence the reason why it is only needed by WebServices.
Setting up a SAF system does appear to be fairly straight forward, but there are a number of gotchas. It’s unlikely however that you are configuring SAF for single server to single server – if you want this, then you are probably going to use another mechanism although it’s possible that you’ll still setup SAF. In a real system, it’s mostly that the JMS destination that you are forwarding to is a distributed destination, and the point of origin will also be a cluster, although a single server or client application are alternatives. So here are the points that I would suggest that you pay attention to, assuming that are using SAF to move message from cluster to cluster.
How To Configure and Test The Saf Agent When Forwarding To A Distributed Destination
This is a guide to set up an example SAF setup. It requires that you configure two domains. In this example, the domain where the SAF Agent is deployed is referred to as the FE domain and the domain containing the distributed destination where messages are forwarded to as the BE domain. Remember that unique names must be used for all JMS related components. Both domains contain two managed servers.
BE Domain Configuration
1) To begin with, create a file store on each migratable target. Strictly speaking there is a default persistence store that is created by default on each managed server, but in setting up and testing most environments won’t rely on this.
2) For each Managed Server you will need to configure a JMS server using the file Store.
Eventually you’ll end up with a JMS server created on both migratable targets.
3) Then you will need to add and target a JMS Module, giving it a meaningful name.
And deploy it to the cluster
For Ease, select the option that will allow you to immediately add JMS deployments to the Module.
4) Within the JMS Module configure a SubDeployment. The SubDeployment points to the JMS Servers and NOT the Managed Servers. Always use SubDeployment for JMS deployment purposes, the default targetting is prone to errors and confusion with anything other than Connection Factories and simple JMS destinations.
5) Within the JMS Module, configure a Distributed Destination and Target to the SubDeployment.
It is important to use the targeting option correctly and target to the subdeployment. You have been warned!
6) Within the JMS Module, create a new resource and select a Connection Factory. For this you can rely on the default targeting, so after naming the resource, simply select finish and allow it to be targeted to the cluster.
If you want to (at this point) you can test the Distributed Destination using the clients that are given later in this document, just point the QueueMultiSend client to the URL for the distributed destination.
FE Domain Configuration
This is where we configure the SAF components. To allow connection to these locally (for testing), we need to also configure a JMS Connection Factory. For this example I’ve targeted to the Migratable Target as the best practice is to use Migratable Target for SAF Agent deployment.
1) Create a file store and target to each Migratable Target that will have a SAF agent on it. This is identical to step 1 in the BE Domain Configuration.
2) Create a SAF Agent for each Migratable Target, so that each managed server will have a SAF Agent.
3) Now create a new JMS module. This is identical to step 3 in the BEDomain configuration.
4) To correctly target the SAF Components, create a Sub Deployment that allows you target the SAF Imported Destination (created later) to the SAF Agents, paying attention to where you are targeting it.
5) To give the details of the remote servers, you need to configure a Remote SAF Context within the JMS Module. This is the component that tells the SAF Agent where the domain containing the JMS destination is for the messages to be forwarded to, so it contains the details of the BE Domain. To do this, you need to go to the Module, select New resource. When presented with the list of resources, select Remote SAF Context.
Edit : there is a mistake in picture here – the url t3://10.16.241.160:15003,10.16.241.160:15005
6) Now you need to create the SAF Error Handling using the Distributed Destination from the FE domain. To do this, you need to go to the Module, select New resource. When presented with the list of resources, select SAF Error Handling.
7) Here is where you create the SAF Imported Destination. You use the SAF Remote Context and SAF Error Destination that you have already created.
Then target using the subdeployment, so ensure you use the Advanced Targeting option.
6) Now add the Distributed Destinations that are hosted by the BE Domain within the SAF Imported Destination. Open the SAF Imported Destination, select the Queue tab.
7) Finally, for testing purposes, we need to create a JMS Connection Factory on the FE Domain side.
Below are two JMS clients (links below) that can be used for testing. In honesty, they are simply altered versions of the JMS example clients that ship with WLS.
For the multi send client the usage is simply
java QueueMultiSend WebLogicURL ConnectionFactory Queue MessageTimes SleepPeriod
To send messages you need to specify the cluster address or the URL of one of the FE Domain Managed Servers, The FEDomain ConnectionFactory and the SAF Queue name. This last one is the tricky one, it means that you need you specify the BE Distributed Destination prefixed by the SAF prefix. In the example that I’ve done here the full JNDI would be FESAFImpDestBEDistributedQueue for accessing the distributed destination through SAF.
For the receive client, the syntax is simply
java QueueReceive WebLogicURL ConnectionFactory Queue
If you want to guarantee which server the consumers are taking messages from, specify the Queue by the member destination name and not the distributed destination name.
I’ll write another article over the next couple weeks on how to track messages and how to debug when this go wong.