Forwarding Messages from WebLogic to TIBCO EMS

Introduction

Messaging is one of those technologies that have been around for decades, but only recently people got aware of the important role that messaging plays to any software-based architecture. Any use case that requires messages to be exchanged between systems in a reliable, fault-tolerant and scalable way may leverage messaging to fulfill its needs. Nowadays we have thousands of messaging products available to use, so deciding which one to pick up shouldn’t be a hard task. One popular option is TIBCO EMS from TIBCO Software.

Because TIBCO’s popularity, it is quite common seeing application-based integrations being handled by this product. That happens because most SI’s (System Integrators) end up building their solutions based on TIBCO’s technology. In this scenario, the solution code is then written to connect to TIBCO and receive messages only from it. From the solution perspective, it does not know which applications are sending the data because it only communicates to TIBCO. While this design may seem interesting due to the decoupling of the data consumer (the solution itself) from the data providers (who effectively create and transmit the data) this may pose some additional challenges for applications that wish to send data to the solution – but for some technical reason cannot connect to TIBCO.

Not being able to connect to TIBCO can be more common than most people think. Often people decide that they will not worry about how their applications are going to connect to TIBCO just because it is a standard-based technology. The standard in this case is the JMS specification. Therefore, they rely on the assumption that their developers will simply write JMS-based code and things will happen smoothly. But the reality is a bit different. Being based on JMS only means that the code needed to interact with the messaging system will be standard, so there would be no code changes if one decides to move from TIBCO to another JMS-based system.

However, in order to properly establish connection the applications must carry some dependencies from the messaging system. Often these dependencies include the libraries that hold the implementation of the objects retrieved by the client code using JNDI – commonly the connection factory and destination objects. If these libraries are not present on the client’s classpath; the code will not be able to deserialize the retrieved objects and thus, it will raise an error. That means that even though the code will not change if the messaging system is replaced, but the overall solution will stop working due to the missing libraries.

This blog is going to detail how you can forward messages from WebLogic to TIBCO EMS using a feature called messaging bridge. When this feature is configured, any message sent to a WebLogic destination will be transparently forwarded to another messaging system. This may be particularly interesting if you have a situation in which messages can only be sent to WebLogic, but you need that the messages end up being sent to another JMS-based system such as TIBCO EMS. A very interesting use case would be an integration built using ICS (Integration Cloud Service) that needs to interact with an On-Premise system through the JMS adapter and the Connectivity Agent.

Overview about the Messaging Bridge

In nutshell; the messaging bridge functionality allows that messages from one JMS-based system can be forwarded to another, whatever if this other JMS-based system is based on the same product or not. For instance; you can have a WebLogic domain forwarding messages to another WebLogic domain, or you can have a WebLogic domain forwarding messages to other JMS-based systems such as TIBCO EMS, IBM MQ, Apache ActiveMQ, FioranoMQ, etc.

One of the greatest advantages of the messaging bridge feature is that it truly decouples producers and consumers. Of course; that ought to be the primary goal of any JMS-based system, but as we discussed earlier there are dependencies that must be taken care of before one application be able to read and/or write any data. By using messaging bridge however, these whole dependencies problem stops being a concern of the applications and starts to be a concern of WebLogic – who will transparently forward the messages no matter if it is between the same or different JMS-based products.

Pragmatically speaking, the messaging bridge will forward any message sent to a source destination to a target destination. Figure 1 shows how WebLogic implements the messaging bridge functionality.

Messaging_Bridge

Figure 1: Implementation of the messaging bridge functionality.

As you can see in figure 1, WebLogic leverages its specialized JCA resource adapters to connect to source and target JMS systems. These adapters take care of the job of establishing the underlying connections, performing transactions and managing the allocated resources. The core behavior implemented on the JCA adapter relies on the ability to continuously listen for messages sent to the source destination. If a new message arrives; the JCA adapter fully reads it and tries to send to the target destination, using the QoS set in the messaging bridge. If the QoS is set to “Exactly-Once” then only one copy of the message will be delivered to the target destination, even if the server crashes or if there is some downtime in the network. Other QoS options are also available, such as “At-Least-Once” and “At-Most-Once”.

It is up to the user the configuration of the source and target destinations. That means that the user is responsible for configuring the details that will be the foundation for the JCA resource adapter behavior. Such details include providing the initial factory class, the connection factory JNDI name, the destination JNDI name, the connection URL, credentials and type of destination. If either the source or the target destination is not WebLogic, then the user is also responsible for deploying in WebLogic’s classpath any required library from the JMS system.

Although one may argue that the messaging bridge is too complicated to understand, its configuration is indeed very straightforward. There are three main steps to get messaging bridge up-and-running:

1) Configuration of the Source Destination

2) Configuration of the Target Destination

3) Configuration of the Messaging Bridge

The following sections will demonstrate how to set up messaging bridge so messages from a WebLogic domain can be forwarded to TIBCO EMS. The use case will demonstrate how orders sent to a WebLogic queue can be automatically forwarded to a TIBCO queue. That way, consumers can plug themselves into TIBCO and process the messages accordingly.

Configuration of the Source Destination (WebLogic)

This section is going to detail the steps necessary to configure the source destination. Since the source of the messages is WebLogic, the first step is making sure that we have all the JMS resources created. Therefore, create a new connection factory called “WLS.ConnFact” and one distributed queue called “WLS.OrderQueue”. Figure 2 shows these two JMS resources created in WebLogic:

Creating_WLS_JMS_Resources

Figure 2: The JMS resources being created in WebLogic.

Always make sure that the connection factory created supports XA transactions. If the QoS chosen for the messaging bridge is “Exactly-Once” then the connection factory needs to support XA transactions. It might be not required if another QoS is chosen. However; if the connection factory does not support XA transactions and “Exactly-Once” is chosen, then the JCA resource adapter is not going to be able to enlist the connection factory into the global transaction and therefore – an error will be raised by the adapter.

With the JMS resources properly created on WebLogic, now it is time to create the source destination. The source destination represents the destination where the messaging bridge will pick up the messages and send to the target. In this case, we want that messages from WebLogic to be sent to TIBCO. Thus, go ahead and create a JMS bridge destination for WebLogic. In the Administration Console, go to Services > Messaging > Bridges > JMS Bridge Destinations and click on the new button. Fill up the information necessary to establish connection to WebLogic; as well as the information about the JMS resources, as shown in figure 3.

Creating_Bridge_Destination_WebLogic

Figure 3: The JMS Bridge destination for WebLogic.

The information shown in figure 3 is specific to WebLogic and how to connect to a particular group of servers. For instance, the “Connection URL” field shows a group of servers that represent the managed servers for a given WebLogic cluster, using the T3 protocol. Trying to use the same information on other type of JMS systems will naturally result in errors. Thus, keep in mind the product specifics while setting these parameters.

Configuration of the Target Destination (TIBCO EMS)

This section is going to detail the steps necessary to configure the target destination. Since the target of the messages is TIBCO EMS, the first step is making sure that we have all the JMS resources created. Therefore, create a new XA connection factory called “TIBCO.ConnFact” and one simple queue called “TIBCO.OrderQueue”. Figure 4 shows the sequence of commands that must be used to create these JMS resources on TIBCO EMS. The commands were executed using a tool called TIBCO EMS Admin Tool.

Creating_JMS_Resources_in_TIBCO

Figure 4: Creating the JMS resources on TIBCO EMS.

Most commands shown in figure 4 are self explanatory since they mimic plain English. The first command issues the creation of a connection factory named “TIBCO.ConnFact” that points to a TIBCO EMS install located in the given URL. The connection factory created is also generic, meaning that it can be used for both point-to-point (Queue) and Publish/Subscribe (Topic) cases. Finally, the connection factory created supports XA.

The second command issues the creation of a queue named “TIBCO.OrderQueue”. The given name is internal to TIBCO and therefore – does not represent the queue JNDI name. For this reason, we have the third command that explicitly creates a JNDI name for the queue created.

With the JMS resources properly created on TIBCO EMS, now it is time to create the target destination. The target destination represents the destination where the messaging bridge will send the messages to. In this case, we want that messages from WebLogic to be sent to TIBCO. Thus, go ahead and create a JMS bridge destination for TIBCO. In the Administration Console, go to Services > Messaging > Bridges > JMS Bridge Destinations and click on the new button. Fill up the information necessary to establish connection to TIBCO; as well as the information about the JMS resources, as shown in figure 5.

Creating_Bridge_Destination_TIBCO

Figure 5: The JMS Bridge destination for TIBCO EMS.

Keep in mind that the initial context factory used here differs from what we used on figure 3. Although not properly shown in figure 5, the correct value to be set in the “Initial Context Factory” field is:

– com.tibco.tibjms.naming.TibjmsInitialContextFactory

Also, it is important to note that this class will not be available on WebLogic’s classpath by default. Thus, you need to copy the TIBCO library that holds that class into WebLogic’s classpath. You can grab a copy of this library in the following location:

– $TIBCO_HOME/tibco/ems/$VERSION/lib/tibjms.jar

Configuration of the Messaging Bridge

Now it comes the most interesting part of the configuration: the creation of the messaging bridge itself. So far all we have is the definition of where to pick the messages up (the source destination) and where to send it off (the target destination) but there is nothing actually created that will make that happen. That is why we need to create a messaging bridge in WebLogic. In the Administration Console, go to Services > Messaging > Bridges and click on the new button. Enter the required information asked and click in next. The two most important fields to set are the “Quality of Service” and “Started”; since they will dictate how transactions are going to be handled during the processing of messages, and what is going to be the initial state of the messaging bridge service after its creation. Figure 6 depicts this.

Creating_Bridge_1

Figure 6: Creating a messaging bridge in WebLogic.

The following pages of the wizard will ask information about who is going to be the source of the bridge and who is going to be the target. Make sure to specify WebLogic as the source and TIBCO as the target. Also, the wizard also asks which messaging provider is used for each destination. In case of TIBCO, you need to select the “Other JMS” option. Finally, the wizard also asks information about where to deploy the bridge. The best practice is targeting the bridge to a cluster with at least two managed servers. That way you can tolerate server failures without disrupting the bridge processing. This is going to be further detailed in the “Important Technical Considerations” section. Figure 7 shows the bridge fully configured.

Creating_Bridge_2

Figure 7: Creating a messaging bridge in WebLogic.

When you complete the wizard, the messaging bridge service will be deployed on the servers defined in the target page. Therefore; once you start these servers, the service will also start and ensure that any message sent to the WebLogic destination will be forwarded to TIBCO EMS. You can easily check if the service is up-and-running by clicking in the monitoring tab (while being in the messaging bridge page) and checking for the columns state and description. If the state column displays “Active” and the description column displays “Forwarding messages” then everything is working as expected. Figure 8 depicts this.

Checking_Monitoring_Page

Figure 8: Checking the status of the messaging bridge.

Now that we have the messaging bridge properly configured, we can start the testing to see if messages sent to WebLogic will be transparently forwarded to TIBCO EMS. This is going to be covered in the next section, where it will be detailed how to create a Java application that connects to TIBCO EMS to listen for messages.

Checking if the Messaging Bridge is Working

The best way to check if TIBCO EMS is receiving messages sent by the messaging bridge service is, having an application that connects to TIBCO and listens for messages sent to the “TIBCO.OrderQueue” queue. The listing 1 shows the code necessary to test the messaging bridge functionality. Before executing the code, make sure that the TIBCO libraries are available on the application’s classpath.

package com.oracle.ateam.jms.sample;

import java.util.Properties;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.XAConnectionFactory;
import javax.naming.Context;
import javax.naming.InitialContext;

public class ReceiveMessagesFromTIBCO {

	public void run() throws Exception {
		
		final Properties environment = new Properties();
		environment.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.tibco.tibjms.naming.TibjmsInitialContextFactory");
		environment.setProperty(Context.PROVIDER_URL, "tcp://soa.suite.vm:7222");
		environment.setProperty(Context.SECURITY_PRINCIPAL, "admin");
		environment.setProperty(Context.SECURITY_CREDENTIALS, "admin_passwd");
		
		InitialContext jndiContext = null;
		XAConnectionFactory connFact = null;
		Queue queue = null;
		
		Connection conn = null;
		Session session = null;
		MessageConsumer msgCons = null;
		
		try {
			
			jndiContext = new InitialContext(environment);
			connFact = (XAConnectionFactory) jndiContext.lookup(FACTORY_JNDI_NAME);
			queue = (Queue) jndiContext.lookup(QUEUE_JNDI_NAME);
			
			conn = connFact.createXAConnection();
			session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
			msgCons = session.createConsumer(queue);
			msgCons.setMessageListener(new MessageListener() {
				
				@Override
				public void onMessage(Message message) {
					
					TextMessage textMsg = (TextMessage) message;
					
					try {
						
						System.out.println(textMsg.getText());
						
					} catch (JMSException ex) {
						
						ex.printStackTrace();
						
					}
					
				}
				
			});
			
			conn.start();
			
			for (;;) {
				
				Thread.sleep(1000); // Ensures that the JVM keep running...
				
			}
			
		} catch (Exception ex) {
			
			ex.printStackTrace();
			
		} finally {
			
			msgCons.close();
			session.close();
			conn.close();
				
		}
		
	}

	public static void main(String[] args) throws Exception {
		
		new ReceiveMessagesFromTIBCO().run();
		
	}
	
	private static final String FACTORY_JNDI_NAME = "TIBCO.ConnFact";
	private static final String QUEUE_JNDI_NAME = "TIBCO.OrderQueue";
	
}

Listing 1: Java application that connects to TIBCO to listen for messages.

The code shown in listing 1 uses the JMS API to connect to TIBCO EMS and listen for received messages. The logic written in the code relies on the creation of a message listener that is kept continuously live to receive messages sent to the destination. Once a message is received, its contents will be printed out in the output console. Therefore, make sure to grab the output console of the application to see the result.

In order to send a message to the WebLogic destination, you can use WebLogic’s built-in JMS client or; you can write a Java application that uses the JMS API to create a producer. For the sake of simplicity, it is preferable to use WebLogic’s built-in JMS client. Thus; in the Administration Console, go to Services > Messaging > JMS Modules > JMS Module > WLS.OrderQueue. This will open the settings for the JMS queue. Click on the monitoring tab and then select one of the servers in which the queue is deployed. After doing this the “Show Messages” button will be available to use. Click on this button to open the page that allows you to create a new message for the queue. Figure 9 shows an example of message.

Creating_New_Message

Figure 9: Creating a new message for the WebLogic queue.

Once you hit the OK button, the message will be sent to the WebLogic queue. Internally; the messaging bridge service will detect that a new message has arrived and therefore will execute the forwarding logic configured, which is sending that message to the TIBCO EMS queue.

Important Technical Considerations

The messaging bridge service from WebLogic is quite powerful, but it can be a source of headache when configured for the first time. This section will detail some technical considerations that anyone willing to leverage this service ought to consider.

First, you need to be aware of which JMS version the messaging system implements. That is important because if the messaging system runs a JMS version that is greater than what WebLogic ships, then there will be annoying errors occurring internally. And those errors are not shown unless you set the debugging level to TRACE and you activate some debugging options. For example, listing 2 shows the error message that was thrown by WebLogic when TIBCO 8.3 was used in conjunction with WebLogic 12.1.3.

java.lang.NoSuchMethodError: javax.jms.Message.setJMSDeliveryTime(J)
	at com.tibco.tibjms.TibjmsMessageProducer._publish(TibjmsMessageProducer.java:288)
	at com.tibco.tibjms.TibjmsQueueSender.send(TibjmsQueueSender.java:59)
	at weblogic.jms.adapter.JMSBaseConnection.sendInternal(JMSBaseConnection.java:900)
	at weblogic.jms.adapter.JMSBaseConnection.access$300(JMSBaseConnection.java:89)
	at weblogic.jms.adapter.JMSBaseConnection$9.run(JMSBaseConnection.java:823)
	at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
	at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
	at weblogic.jms.adapter.JMSBaseConnection.send(JMSBaseConnection.java:820)

Listing 2: Error thrown by WebLogic when TIBCO 8.3 was used with WebLogic 12.1.3.

The error is pretty clear. The messaging bridge was not able to start because some classes were found incomplete, with some methods missing. That indicates that the JMS version being used by WebLogic is incompatible with what TIBCO expects. Going further, TIBCO EMS 8.3 was built on top of JMS 2.0, which is the last version of the JMS specification. However, WebLogic 12.1.3 was built on top of JMS 1.1, and therefore is incompatible with the TIBCO version being used. The solution would be either use a most recent WebLogic version such as version 12.2.1 or; use an old version of TIBCO that supports JMS 1.1. Figure 10 summarizes the WebLogic releases required.

Table

Figure 10: Summary of the WebLogic releases required.

Another important aspect to consider is about fault-tolerance and scalability. If the use case being built on top of the messaging bridge service relies on these attributes, then you should take extra care while designing the solution. As mentioned before, the messaging bridge is implemented using some special JCA adapters provided by WebLogic. When the messaging bridge service is deployed, what happens is that those adapters are deployed on each server that you set as target. If there is only one server, then it will be the SPOF (Single Point of Failure) of the architecture. For instance, if the server crashes then all messages sent to the WebLogic destination will be sitting there until the server comes back, because it was the only server capable of forwarding messages to TIBCO. The best practice here is to have a redundancy of servers- preferably a cluster – to ensure that message forwarding never stops.

That leads us to consider another important detail about fault-tolerance. Always try to use distributed destinations to ensure that the destination itself not become a SPOF. Simple queues or topics are pinned to the servers and if these servers crash the destination will become unavailable. Differently, when you use distributed destinations, the destination will exist in more than one server and therefore; will ensure extra high availability for the destinations, even in the event of one or multiple server crashes.

Using multiple servers in WebLogic can be also useful for scalability purposes. If a single server is used, then it will be the SPOB (Single Point of Bottleneck) of the architecture. That might happen if the volume of messages increases then you would need multiple servers to drain messages out of WebLogic and do the forwarding, so the message consumption could keep up with message production. Otherwise, you might start seen messages being accumulated in the destination because they are not being consumed in a timely fashion.

Finally, be aware of which migration policy the messaging bridge service is using. There are two options available, the “Distributed” and “Singleton” option. Those options can be found when you open the page that holds the settings for the messaging bridge; under the high availability tab. Figure 11 shows these options.

MB_Distribution_Policy

Figure 11: Configuring the appropriate distribution policy.

The migration policy option controls where the messaging bridge service will be deployed. If the option chosen is “Distributed” (which by the way is the default option) then the service will be deployed on all servers or clusters set as target. If the “Singleton” option is chosen then WebLogic will pick up only one server from a set of servers set to host the messaging bridge service. So; unless you are dealing with a use case that requires messages to be delivered in a specific order, it would be preferable to always use the “Distributed” policy.

Conclusion

WebLogic provides several out-of-the-box features to handle messaging scenarios, and one of them is the messaging bridge service. This feature may be useful if you need to transparently forward messages to other messaging systems, even if you wrote the code to connect only to WebLogic. This feature may be suitable for scenarios where you need to send messages to other messaging systems but for some reason you are tied to developing code to WebLogic.

This blog has shown the steps necessary to configure the messaging bridge service, and how can you use this feature in conjunction with TIBCO EMS, one of the most messaging systems used out there. The tips shared by this blog can be useful if you are using the JMS adapter from ICS (Integration Cloud Service) and are trying to integrate Cloud-based applications with JMS messaging systems On-Premise.

Add Your Comment