Thursday, 15 January 2015

Integration of MSCRM with TIBCO ESB

Requirements for integrating Dynamics CRM with the other systems  is to use Tibco Enterprise Service Bus as the only communication layer.


The communication with Tibco ESB is the main integration point for Dynamics CRM. It must replace SAP CRM endpoints and also support a new communication channel with SAP IS-U.

1.       Outbound communication from Dynamics CRM
In order to perform web service calls to an external system, the plugin extension capabilities of Dynamics CRM are used. Plugins are pieces of custom C# code that are triggered on a specific system event and implement custom business logic. The integration approach uses plugins to communicate with TIBCO ESB.
The advantages of using plugins for integration purposes include the following:
        Make use of the power of .NET libraries;
        Support both synchronous and asynchronous execution. If ran asynchronously, plugins execute behind the scenes and do not interact with user activities;
        Provide out of the box logging mechanism inside the CRM for auditing and error logging;
        Can be configured to run in various Steps of the execution pipeline within CRM: pre-event and pre-validation, pre-event and pre-operation, and post-event;
        Provide the triggering entity data in the execution context, both pre and post operation, eliminating the need for additional data queries.
In order to implement the integration with TIBCOESB post a request XML to a Queue or Topic and get a response, the integration approach uses the .NET EMS library provided together with the Tibco documentation. The library handles the authentication mechanism and provides strong classes for establishing a communication with Tibco

1.       Inbound communication to Dynamics CRM
For the inbound integration with Dynamics CRM there are two possible approaches to be considered:
A.      TIBCO calling the MS CRM web services:
        Pro: no custom connector, reduced risk of error;
        Cons: custom TIBCO adapter needed for the CRM authentication through ADFS, higher implementation cost.
B.      Using a custom WCF service to mediate the communication between TIBCO and MS CRM:
        Pro: fast implementation, performance scalability options, interoperability with other technologies;
        Cons: additional custom WCF component to maintain.

///<summary>
/// Sent a request XML to a Tibco Queue
///</summary>
privatevoid SendRequest()
        {
            Connection connection = null;
try
            {
                ConnectionFactory connectionFactory = new ConnectionFactory(serverUrl);
                connection = connectionFactory.CreateConnection(userName, password);
                Session session = connection.CreateSession(false, 1);
                Destination destination = session.CreateQueue(requestQueue);
                MessageProducer messageProducer = session.CreateProducer(null);
                TextMessage textMessage = session.CreateTextMessage(RequestMessage);
if (!string.IsNullOrEmpty(correlationId))
                {
                    textMessage.CorrelationID = correlationId;
                }
                Destination replyTo = session.CreateQueue(responseQueue);
                textMessage.ReplyTo = replyTo;
                messageProducer.Send(destination, textMessage);
            }
catch (EMSException ex)
            {
                tracingService.Trace(ex.Message, newobject[0]);
throw ex;
            }
finally
            {
                connection.Close();
            }
        }

///<summary>
/// Retrieve the synchronous reponse XML from a Tibco Queue
///</summary>
privatevoid GetSyncResponse()
        {
int num = 1;
bool flag = false;
            Connection connection = null;
            Message message = null;
try
            {
                ConnectionFactory connectionFactory = new ConnectionFactory(serverUrl);
                connection = connectionFactory.CreateConnection(userName, password);
                Session session = connection.CreateSession(false, num);
                Destination destination = session.CreateQueue(responseQueue);
string text = "JMSCorrelationID = '" + correlationId + "'";
                MessageConsumer messageConsumer = session.CreateConsumer(destination, text);
                connection.Start();
while (!flag)
                {
                    ReplyMessage = messageConsumer.Receive().ToString();
if (message == null)
                    {
break;
                    }
if (num == 2 || num == 23 || num == 24)
                    {
                        message.Acknowledge();
                    }
                    flag = true;
                }
            }
catch (Exception ex)
            {
                tracingService.Trace(ex.Message, newobject[0]);
throw ex;
            }
finally
            {
                connection.Close();
            }
        }

///<summary>
///  Retrieve the asynchronous XML reponse from a Tibco Queue
///</summary>
privatevoid GetASyncResponse()
        {
            Connection connection = null;
try
            {
                ConnectionFactory connectionFactory = new ConnectionFactory(serverUrl);
                connection = connectionFactory.CreateConnection(userName, password);
                Session session = connection.CreateSession(false, 1);
                Destination destination = session.CreateQueue(responseQueue);
Console.WriteLine("Subscribing to destination: " + responseQueue);
string text = "JMSCorrelationID = '" + correlationId + "'";
                MessageConsumer messageConsumer = session.CreateConsumer(destination, text);
                messageConsumer.MessageHandler += new EMSMessageHandler(_HandleMessage);
                connection.Start();

while (true)
                {
lock (stateLock)
                    {
if (stop)
                        {
                            connection.Stop();
break;
                        }
Thread.Sleep(2000);
                    }
                }
            }
catch (Exception ex)
            {
                tracingService.Trace(ex.Message, newobject[0]);
throw ex;
            }
        }

///<summary>
/// Asynchronous message handler
///</summary>
///<param name="sender"></param>
///<param name="arg"></param>
privatevoid _HandleMessage(object sender, EMSMessageEventArgs arg)
        {
try
            {
                stop = true;
                ReplyMessage = ((TextMessage)arg.Message).Text;
                msg = arg.Message;
            }
catch (Exception ex)
            {
                tracingService.Trace(ex.Message, newobject[0]);
throw ex;
            }
        }