Interoperability between Microsoft and SOA Suite 12c

Introduction

During the design of SOA applications it is inevitable that from time to time you will need to interface with Microsoft-based applications. While technologies like SOAP and REST do a great job when request-reply communication is needed, most people struggle when a messaging-based communication is required. This blog will present two approaches to get messaging working between Microsoft and SOA Suite 12c.

Which Choices Do I have?

SOA Suite 12c offers a complete set of tools to integrate with Microsoft applications using messaging. Which one to use is a simple question of asking where the messaging system resides. If the messaging system to be accessed sits on SOA Suite side (WebLogic JMS) then you should use the WebLogic JMS .NET Client. If the messaging system to be accessed sits on Microsoft side (Microsoft Message Queuing) then you should use the JCA adapter for MSMQ. Using the WebLogic JMS .NET Client allows code written in .NET to access the WebLogic JMS server using the T3 protocol, just like any other Java application. Using the JCA adapter for MSMQ allows SOA composites and OSB applications to send/receive messages to/from MSMQ queues.

Using the WebLogic JMS .NET Client

The implementation of the WebLogic JMS .NET Client is very straightforward. All you have to do is deploy your .NET application with the WebLogic.Messaging.dll assembly file. You still need to code how your application will send/receive messages to/from the WebLogic JMS destinations. You can easily find the WebLogic.Messaging.dll assembly file in the following location: $FMW_HOME/wlserver/modules/com.bea.weblogic.jms.dotnetclient_x.x.x.x.

In the same location you can find the WebLogic JMS .NET Client API documentation. For those of you that are familiar with the JMS API, it will be easy to understand since the API design is almost the same. For beginners, I have provided the following C# sample code that shows how to publish messages to an WebLogic JMS queue.

using System;
using System.Collections.Generic;
using System.Text;
using WebLogic.Messaging;

namespace com.oracle.fmw.ateam.soa
{

    public partial class SampleDotNetApplication
    {

        private void sendMessage()
        {

            IConnectionFactory wlsConnectionFactory;
            IQueue ordersQueue;

            IDictionary<string, Object> environment;
            IContext jndiContext;

            IConnection connection = null;
            ISession session = null;
            IMessageProducer messageProducer = null;
            ITextMessage message = null;

            try
            {

                environment = new Dictionary<string, Object>();
                environment[Constants.Context.PROVIDER_URL] = "t3://soa.suite.machine:8001";
                environment[Constants.Context.SECURITY_PRINCIPAL] = "weblogic";
                environment[Constants.Context.SECURITY_CREDENTIALS] = "welcome1";
                jndiContext = ContextFactory.CreateContext(environment);

                wlsConnectionFactory = jndiContext.LookupConnectionFactory("jms/wlsConnectionFactory");
                ordersQueue = (IQueue) jndiContext.LookupDestination("jms/ordersQueue");

                connection = wlsConnectionFactory.CreateConnection();
                connection.Start();

                session = connection.CreateSession(Constants.SessionMode.AUTO_ACKNOWLEDGE);
                messageProducer = session.CreateProducer(ordersQueue);
                message = session.CreateTextMessage();
                message.SetStringProperty("customProperty", "123456789");
                message.Text = "<message>Oracle SOA Suite 12c Rocks</message>";
                messageProducer.Send(message);

            }
            finally
            {

                messageProducer.Close();
                session.Close();
                connection.Stop();
                connection.Close();

            }

        }

    }

}

Note that in the sample code above, an initial context object is instantiated during every method call. The code was written this way for clarity purposes but in the real world you should avoid this practice. That could lead to potential performance issues as explained in the next section. As a best practice instantiate only one initial context object per CLR process.

// environment = new Dictionary<string, Object>();
// environment[Constants.Context.PROVIDER_URL] = "t3://localhost:7101";
// environment[Constants.Context.SECURITY_PRINCIPAL] = "weblogic";
// environment[Constants.Context.SECURITY_CREDENTIALS] = "welcome1";
// jndiContext = ContextFactory.CreateContext(environment);

/* Get the JNDI context from an local cache manager
 * instead of creating it multiple times. The first
 * call create the instance and the subsequent calls
 * just retrieve it from a private static variable. */

jndiContext = JndiContextManager.getInstance();

wlsConnectionFactory = jndiContext.LookupConnectionFactory("jms/wlsConnectionFactory");
ordersQueue = (IQueue)jndiContext.LookupDestination("jms/ordersQueue");

The above code was slightly modified to handle the JNDI context management, using the Singleton design pattern to restrict the number of instances into just one.

Special considerations when using the WebLogic JMS .NET Client

Before moving applications from development/staging to production, maybe you should step back and take a look in some of the following guidelines:

* Make sure that the T3 protocol is available in the managed server accessed by the .NET application. When pointing to the admin server you don’t have to worry about this, but perhaps other managed servers must have networks channels configured to get this protocol enabled.

* Use the -Dweblogic.protocol.t3.login.replyWithRel10Content=true JVM property to allow WebLogic JMS .NET client applications written prior of 12.1.3 version to interoperate with the 12.1.3 version.

* Be aware that the following features are not currently supported: Queue browsers, XA transactions, SSL, HTTP tuneling, SAF clients, multicast subscribers and automatic reconnect.

* How you implement your messaging code has a significant impact on the overall performance of your application and will affect the rate of message production and/or consumption. According to the Microsoft CLR specification, each process uses a fixed thread pool with 25 threads per available processor. Each time you create an initial context that uses the T3 protocol you burn a thread from that pool and also create a socket connection to the WebLogic server. On the WebLogic server side you also create a thread to handle requests coming from that socket, using the traditional socket-reader muxer thread pool. That means if you create a large number of concurrent initial context objects, there will be a correspondingly large number of socket connections to manage in the client thread pool. You can also run out threads in the client application if the number of initial contexts created exceeds the thread pool size. Consider using one shared initial context per process to optimize the client thread pool and minimize the performance hit on the server incurred when there are too much searches in the JNDI tree.

Using the JCA Adapter for MSMQ

This adapter leverages the jCOM technology available in WebLogic to provide connectivity to the MSMQ server. The first thing to do is enable jCOM in all servers where the adapter will be deployed. You can easily do this using the WebLogic administration console. In the managed server settings page, go to the “Protocols” > “jCOM” tab. Select the “Enable COM” check box as shown in the screen shot below:

Enabling jCOM in WebLogic

Due to the nature of the JCA adapter, you will also need to create an outbound connection pool. In the deployments page, search for the “MSMQAdapter” and then go to the “Configuration” > “Outbound Connection Pools” tab. Create a new javax.resource.cci.ConnectionFactory and provide it with a proper JNDI name. After that click in the newly created outbound connection pool and go to the “Properties” tab. Here is the summary of the main properties:

Property Name Description Possible Values
AccessMode Identifies if the connection factory allow native access or not. If native, the SOA server should be installed on the same host as the MSMQ server. Using the SOA server co-located with MSMQ provides better performance. Use DCOM only when accessing the MSMQ server remotely.  Native | DCOM
Domain Domain of the MSMQ host. Any java.lang.String value
Host  IP address or machine name of the MSMQ host. Any java.lang.String value
Password  Password for the specified user.  Any java.lang.String value
TransactionMode Indicates if the connection participates in a transaction when sending and receiving a message. Use single only if the MSMQ queue is transactional, otherwise use none. Single | None 
User Identifies a user. Any java.lang.String value

After setting these properties, you can optionally go to the “Connection Pool” tab and fine tune the connection pool, specifically the “Initial Capacity”, “Max Capacity” and “Capacity Increment” parameters. That’s it, this is the minimal configuration needed to start using the JCA adapter for MSMQ. The following section discusses some special considerations for this adapter.

Special considerations when using the JCA adapter for MSMQ

Using the JCA adapter for MSMQ in JDeveloper is equal to any other SOA Suite technology adapter. All you need to do is drag it from the components palette to the composite designer and inform the wizard about the JNDI name of the adapter and details about the queue.

msmq-adapter-config-wizard

But before start deploying applications into the SOA server, review the follow recommendations to help ensure connectivity, high availability and performance:

* If you intend to access public queues and/or distribution lists, an Active Directory Domain Services (AD_DS) must be configured on a Windows 2008 Server system. This requirement does not apply for private queues.

* When the SOA server is not co-located with the MSMQ server or is installed in an operating system different than Windows (e.g.: Linux, Solaris) you need to use DCOM as access mode. in that case you need to set the value of the property “AccessMode” to “DCOM”. In addition, you need to install the MSMQ DCOM Proxy in the machine where the MSMQ server is running.

When the MSMQ Adapter needs to make an outbound connection to the MSMQ server, it must sign on with valid security credentials. In accordance with the J2CA 1.5 specification, the WebLogic server supports both container-managed and application-managed sign-on for outbound connections. The MSMQ adapter can leverage either of these methods to sign on to the EIS. The credentials must include a user that has proper permissions to interact with the MSMQ server otherwise you will get exceptions during deployment.

* The MSMQ adapter supports high availability through the active-active topology. It has a poller thread to poll the queue for the next available message. Each poller thread uses the MSMQ receive API and only removes the message from the queue after successful read. This ensures there is no message duplication when the MSMQ Adapter is deployed in an active-active topology.

* Use the adapter.msmq.dequeue.threads binding property to increase the number of poller threads during endpoint activation. The default value of this property is “1″ which is good for simple tests but with a higher value you can achieve a better degree of parallelism. You can set this property at runtime using the Enterprise Manager FMW Control Console.

increasing-the-poller-threads-count

* Enabling streaming during MSMQ message consumption can significantly reduce the SOA server memory footprint when large payloads are used, specially if there is a mediator applying content-based routing rules before delivering the message for processing.

Conclusion

Enterprise application developers and architects today rarely ask the “Why SOA?” question. They are more often asking about how to implement SOA using best practices in order to build robust and scalable applications that maximize their SOA infrastructure investment. SOA Suite 12c has been designed to be the “Industrial SOA” solution that organizations need to deliver these solutions. Hopefully this blog has provided some useful information and best practices on integrating Microsoft-based applications with SOA Suite 12c using messaging.

Comments

  1. Alexandre Santos says:

    Congrats A-team Ricardo. Excellent article !!

Add Your Comment