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;
}
}