Point-to-Point Messaging using Azure Service Bus Queues

Summary

Here is a quick snippet of code demonstrating how Point-to-point messaging works with Azure Service Bus and the Microsoft Dataverse.

The Microsoft Dataverse emits a message that is pushed into a Service Bus Queue. Message settlement is abstracted away (you do not need to implicitly settle a message). Once a message lands in the Service Bus Queue, the Receiver (an Azure Function) picks up the message (short polling).

Code

using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using Microsoft.Xrm.Sdk;
using System;
using System.Data.SqlClient;
using System.IO;
using System.Text;

namespace EIP_PointtoPoint_Messaging
{
    public class Pointotpoint
    {
        [FunctionName("AddUserService")]
        public void Run([ServiceBusTrigger("eax02", Connection = "SBConnection")] string myQueueItem, ILogger log)
        {
            log.LogInformation($"C# ServiceBus queue trigger function processed message: {myQueueItem}");

            // Create an Execution Context
            RemoteExecutionContext ExecutionContext = DeserializeJsonString<Microsoft.Xrm.Sdk.RemoteExecutionContext>(myQueueItem);
            Microsoft.Xrm.Sdk.Entity targetEntity = (Microsoft.Xrm.Sdk.Entity)ExecutionContext.InputParameters["Target"];
            Contact contact = new Contact();

            contact.FirstName = targetEntity.Attributes["firstname"].ToString();
            contact.LastName = targetEntity.Attributes["lastname"].ToString();
            contact.Email = targetEntity.Attributes["emailaddress1"].ToString();
            contact.ID = targetEntity.Id.ToString();

            // Add to SQL
            AddTableRow(contact);
        }

        public static RemoteContextType DeserializeJsonString<RemoteContextType>(string jsonString)
        {
            //create an instance of generic type object
            RemoteContextType obj = Activator.CreateInstance<RemoteContextType>();
            MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString));

            System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());
            obj = (RemoteContextType)serializer.ReadObject(ms);
            ms.Close();

            return obj;
        }

        public static void AddTableRow(Contact contact)
        {
            try
            {
                SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
                builder.DataSource = "eax100.database.windows.net";
                builder.UserID = "<username-securestring-keyvault";
                builder.Password = "<password-securestring-keyvault>";
                builder.InitialCatalog = "<initial-catalogue-securestring-keyvault)";

                using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
                {
                    String sql = @$"INSERT INTO dbo.Contacts (Firstname, LastName, Email, ContactID, Service)
                                   VALUES ('{contact.FirstName}', '{contact.LastName}', '{contact.Email}', '{contact.ID}', 'Community')";

                    using (SqlCommand command = new SqlCommand(sql, connection))
                    {
                        connection.Open();
                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                Console.WriteLine("{0} {1}", reader.GetString(0), reader.GetString(1));
                            }
                        }
                    }
                }
            }
            catch (SqlException e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    }

    public class Contact
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string Email { get; set; }

        public string ID { get; set; }

        public string Service { get; set; }
    }
}