Friday, October 28, 2016

How To: CRM Online & Azure Bus Integration
Dynamics CRM and Azure together can give much potential by integrating them. This blog post explains how to integrate and effectively make use of it.
One side Dynamics CRM, a feature overloaded SaaS on the other side Azure – a feature rich cloud platform with multiple powers grown as IaaS and PaaS. By integrating Dynamics CRM and Azure the enterprise can utilize both SaaS, IaaS and PaaS. Without any further explanation on this I believe you can understand how much power this *-As-A-Service can bring.
With those power packed performance here we are going to consume a little bit to integrate both of them. 

Required services/tools
  •  Valid Azure subscription, you can always get a 30 days trial account.
  •  Dynamics CRM subscription, this also has a 30 days trial account.
  •  CRM Plugin registration tool

MS Dynamics CRM can be integrated with MS Azure by CRM’s Azure aware event execution pipeline (pug-ins) and Service bus of Azure.
Scope of the integration:
Ø  Delegating complex operations to outside of CRM environment.
Ø  As Azure is Microsoft’s cloud platform out-of-the-box extensions available with SDK to integrate them.
Ø  Safe and secure message communication.
Ø  Single and multiple pipe message posting techniques.
Ø  Listeners can be hosted in cloud or in on premise.
Elements involved:
Ø  Azure Service bus:
o   Service bus is the medium of message transportation between CRM plug-ins and Listeners.
Ø  Listener:
o   An application/service to listen to the messages posted on the Service bus by Plug-ins
Ø  Service End point:
o   Holds the authorization information about Service bus essentially the service bus namespace address and SAS key. This acts like the endpoint to a service foe Service bus but with authorization token.
Ø  Plug-in:
o   This plug-in will be called as Azure-aware as it’ll talk to the Azure service bus via service end point. The service endpoint id will be used in the plug-in to make it aware of the respective service bus.
Ø  Triggers:
o   An action, in which the plug-in will be initiated.

Process flow:
Ø  The user triggers the specific action which bound to plug-in.
Ø  Plug-in process started, posting message using IServiceEndpointNotificationService to Azure service bus.
Ø  Service bus receives the message.
Ø  Listener gets the message processing it.
Ø  Posts back to CRM using Organization service proxy.
Tutorial:
Creating Service bus namespace and getting tokens:
·         Login to the portal.azure.com
·         Create a new Service bus from left menu pane. 

·         Enter a namespace name, select an appropriate subscription. 

·         Then select a resource group and region where it should be hosted.
·         Then click on the create button to create a Service bus.
·         Go to the created service bus namespace.
·         Select the shared access policies from the left pane of service bus window. 

·         Open the RootManageSharedAccessKey.
·         The Connection string – Primary is the value we needed in next step. 

Creating the Service Endpoint.
·         Open up the Plug-in registration tool and connect to the CRM.
·         On the Register button, select Register new Service End point.
·         Paste the Connection string in the text field of the opened dialog. 

·         Click next and save it. The values will be auto populated from the Connectionstring. 

·         Once the Service end point is created, click on the Service Endpoint and go to the properties tab.
·         Select the ServiceEndpointId – which is needed for the next step.
Creating Azure aware Plug-in:
·         I assume you know about the Plug-in creation.
·         In the plug-in Execute method, paste the following code
IOrganizationService service = null;
IPlugincontextcontext = executionContext.GetExtension<IPlugincontext>();
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
service = serviceFactory.CreateOrganizationService(context.UserId);
IServiceEndpointNotificationService endpointService =                                 executionContext.GetExtension<IServiceEndpointNotificationService>();
context.InputParameters["Param"] = "From Plug-In";
  string output = endpointService.Execute(“serviceendpoint”, <serviceendpoint id>), context);
·         Register the assembly using Plugin registration tool.
·         Fill in all the other values and create the Plug-in.
Creating Azure Cloud service:
·         We will be using Azure cloud service to host our listener. And our cloud service is a worker role type.
·         Create a cloud service in Azure.
·         In Visual studio create a new project with Cloud service template.
·         In WorkerRole.cs paste the following code,
namespace CTCloudServiceWorkerRole
{
    public class WorkerRole : RoleEntryPoint, ITwoWayServiceEndpointPlugin
    {
        private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        private readonly ManualResetEvent runCompleteEvent = new ManualResetEvent(false);
        private string OrganizationName;
        private CancellationTokenSource _cancellationTokenSource;
        public override void Run()
        {
            Trace.TraceInformation("CloudServiceWorkerRole is running");
         

            try
            {
                this.RunAsync(this.cancellationTokenSource.Token).Wait();
            }
            finally
            {
                this.runCompleteEvent.Set();
            }
        }

        public override bool OnStart()
        {
            // Set the maximum number of concurrent connections
            ServicePointManager.DefaultConnectionLimit = int.MaxValue;

            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

            // Activate the Listener
            CRMFacade.Instance.Init();
            MetaDataCache.Instance.Init();
            ActivateListener();
            bool result = base.OnStart();

            Trace.TraceInformation("CloudServiceWorkerRole has been started");

            return result;
        }

        public void ActivateListener()
        {
            ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Http;
            var appSettings = ConfigurationManager.AppSettings;
            // Add service bus namespace
            string serviceNamespace = appSettings["serviceNamespace"];

            // Add Default issuer name
            string issuerName = appSettings["issuerName"];

            // Add Service bus Default Key
            string issuerKey = appSettings["issuerKey"];

            string servicePath = “WorkerRole";

            // Leverage the Azure API to create the correct URI.
            Uri address = ServiceBusEnvironment.CreateServiceUri(
                Uri.UriSchemeHttps,
                serviceNamespace,
                servicePath);

            // Create the shared secret credentials object for the endpoint matching the
            // Azure access control services issuer
            var sharedSecretServiceBusCredential = new TransportClientEndpointBehavior()
            {
                TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(issuerName, issuerKey)
            };

            // Using an HTTP binding instead of a SOAP binding for this endpoint.
            WS2007HttpRelayBinding binding = new WS2007HttpRelayBinding();
            binding.Security.Mode = EndToEndSecurityMode.Transport;

            // Create the service host for Azure to post messages to.
            ServiceHost host = new ServiceHost(typeof(WorkerRole));
            ((ServiceBehaviorAttribute)host.Description.Behaviors[typeof(ServiceBehaviorAttribute)]).InstanceContextMode = InstanceContextMode.Single;
            host.AddServiceEndpoint(typeof(ITwoWayServiceEndpointPlugin), binding, address);

            // Create the ServiceRegistrySettings behavior for the endpoint.
            var serviceRegistrySettings = new ServiceRegistrySettings(DiscoveryType.Public);
            ServicePointManager.SetTcpKeepAlive(true, 1000, 1000);
            ServicePointManager.Expect100Continue = false;
            // Add the service bus credentials to all endpoints specified in configuration.

            foreach (var endpoint in host.Description.Endpoints)
            {
                endpoint.Behaviors.Add(serviceRegistrySettings);
                endpoint.Behaviors.Add(sharedSecretServiceBusCredential);
            }

            // Begin listening for messages posted to Azure.
            host.Open();
        }

        public override void OnStop()
        {
            Trace.TraceInformation("CloudServiceWorkerRole is stopping");

            this.cancellationTokenSource.Cancel();
            this.runCompleteEvent.WaitOne();

            base.OnStop();

            Trace.TraceInformation("CloudServiceWorkerRole has stopped");
        }

        private async Task RunAsync(CancellationToken cancellationToken)
        {
            // TODO: Replace the following with your own logic.
            while (!cancellationToken.IsCancellationRequested)
            {
                //Trace.TraceInformation("Working");
                await Task.Delay(1000);
            }
        }

        public string Execute(RemoteExecutionContext executionContext)
        {
           
            return (string)(executionContext.InputParameters["Param”]);
           
        }
    }
}
·         As we need to return a value, we will be deriving the ITwoWayServiceEndpointPlugin.
·         Package the code and upload it to Azure Cloud service.
·         As the service started running, we can go ahead and trigger the Plug-in which will post and receive a message from Azure Service bus.

That’s all the little tutorial about the Azure – CRM integration using Service bus and a hosted worker role listener. Feel free to ask questions in the comment box.