Using RabbitMQ as a message broker in Dynamics CRM data interfaces – part 5

This the final post in my five-part series on creating loosely coupled data interfaces for Dynamics CRM using RabbitMQ. In part 3 and part 4 I showed two approaches for building a Dynamics CRM plug-in that publishes notification messages to a RabbitMQ exchange. In today’s post I will show how to create a Windows console application that reads messages from a queue and writes the data to Dynamics CRM. The code for this application is available on GitHub in the LeadWriterSample project under the LucasCrmMessageQueueTools solution.

The approach

This application is extraordinarily simple. On startup it prompts the user to supply connection information for the RabbitMQ queue that it will monitor as well as a Dynamics CRM connection string. It then monitors the queue for new JSON-formatted messages. When new messages arrive, it attempts to deserialize them into a lightweight "leadtype" object, and then it creates new lead records in CRM. Once a message is successfully processed and a lead is created, the application then sends a confirmation back to RabbitMQ so that the message can be removed from the queue.

The following code shows what happens after a connection to the RabbitMQ is established:

//wait for some messages
var consumer = new QueueingBasicConsumer(channel);
channel.BasicConsume(_queue, false, consumer);
 
Console.WriteLine(" [*] Waiting for messages. To exit press CTRL+C");
 
//instantiate crm org service
using (OrganizationService service = new OrganizationService(_targetConn))
{
   while (true)
   {
     //get the message from the queue
     var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
 
     var body = ea.Body;
     var message = Encoding.UTF8.GetString(body);
 
     try
     {
       //deserialize message json to object
       LeadType lead = JsonConvert.DeserializeObject<LeadType>(message);
 
       try
       {
         //create record in crm
         Entity entity = new Entity("lead");
         entity["firstname"] = lead.FirstName;
         entity["lastname"] = lead.LastName;
         entity["subject"] = lead.Topic;
         entity["companyname"] = lead.Company;
         service.Create(entity);
 
         //write success message to cli
         Console.WriteLine("Created lead: {0} {1}", lead.FirstName, lead.LastName);
 
         //IMPORTANT - tell the queue the message was processed successfully so it doesn't get requeued
         channel.BasicAck(ea.DeliveryTag, false);
       }
       catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex)
       {
         //return error - note no confirmation is sent to the queue, so the message will be requeued
         Console.WriteLine("Could not create lead: {0} {1}", lead.FirstName, lead.LastName);
         Console.WriteLine("Error: {0}", ex.Message);
       }
     }
     catch(Exception ex)
     {
       //return error - note no confirmation is sent to the queue, so the message will be requeued
       Console.WriteLine("Could not process message from queue");
       Console.WriteLine("Error: {0}", ex.Message);
     }
   }
}

If this were to be used in production, I would have created a Windows service instead of a console application, but I wanted to make it easy to try out different connection parameters.

Verifying the application

The queuewriter.js application in the node-app directory in the GitHub repository contains a sample web page that can be used to publish lead data to the CRM-Leads queue. If the application is running, you can access the web page at http://<YOUR_SERVER_NAME>:3000/leadform. When the form’s submit button is clicked, an AJAX call posts a JSON object to the Node.js POST endpoint I showed in my previous post. If the LeadWriterSample console application is running, it will take the message from the queue and you will see a new lead record created in CRM. The screenshots below show each piece working.

5-01-lead-form.PNG
The lead has been submitted via the web form, and a success message has been received from the Node.js endpoint.

5-02-lead-queue.PNG
The lead has landed in the CRM-Leads queue and is ready to be retrieved.

5-03-lead-processed.PNG
The console application has retrieved and processed the submitted lead message.

5-04-lead-crm.PNG
The lead record has been created in CRM.

One caveat about the demo lead form is that it has the RabbitMQ credentials embedded in the HTML source, so this code should not be used in production. My approach was originally formulated with the thought that a server-side process would build the JSON message to post to Node.js, so sensitive information would not be exposed. If you decide to use an AJAX post operation like is shown here, you would want to modify the queuewriter.js application to contain the credentials so they do not need to be passed from the end user’s web browser.

Wrapping up

That does it for this series, but I’ve just barely explored the capabilities of RabbitMQ. There’s so much more you can do with it than what I’ve shown here, and I hope I’ve piqued your interest about how you can use RabbitMQ or any other message broker in your Dynamics CRM projects. If you have any questions or want to continue the discussion, please share your thoughts in the comments.

A version of this post was originally published on the HP Enterprise Services Application Services blog.

comments powered by Disqus