2016-11-25

Microsoft Dynamics CRM and Azure cloud together can bring great potential to any technology solution. This brings us to the point of integrating these two systems. We had previously shown you how to integrate Azure with Dynamics CRM employing the on premise listener. Apart from this method, we can also use the two way listener using Azure service runtime and Azure hosted cloud service to achieve the same integration. This would be another means to communicate to the Azure service bus from Dynamics CRM, and the two way listener can also respond with some processed values to the CRM system. This post looks to understand how to effectively integrate and use this combination to achieve superior results from your technology solution.

Microsoft Dynamics CRM is a feature rich SaaS platform whereas Azure – a diverse cloud platform with multiple powers grown as IaaS and PaaS. By integrating Dynamics CRM and Azure the enterprise can utilize SaaS, IaaS and PaaS. Without any further explanation, you can see how powerful this *-As-A-Service can turn out to be. With these power packed performances here we understand how 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 Azure by CRM’s Azure aware event execution pipeline (plug-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

Service bus is the medium of message transportation between CRM plug-ins and Listeners

Listener

An application/service to listen to the messages posted on the Service bus by Plug-ins

Service End point

Holds the authorization information about Service bus, namely, the service bus namespace address and SAS key. This acts like the endpoint to a service for the Service bus but with an authorization token

Plug-in

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

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



2. Create a new Service bus from left menu pane



3. Enter a namespace name, select an appropriate subscription

4. Then select a resource group and region where it should be hosted

5. Then click on the create button to create a Service bus

6. Go to the created service bus namespace



7. Select the shared access policies from the left pane of service bus window

8. Open the RootManageSharedAccessKey

9. The Connection string – Primary is the value we needed in next step

Creating the Service Endpoint

1. Open up the Plug-in registration tool and connect to the CRM

2. On the Register button, select Register new Service End point

3. Paste the Connection string in the text field of the opened dialog

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

5. Once the Service end point is created, click on the Service Endpoint and go to the properties tab

6. Select the ServiceEndpointId – which is needed for the next step

Creating Azure aware Plug-in

Plug-in creation

1. 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);

2. Register the assembly using Plugin registration tool

3. 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 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.

And that’s all, folks!

Here you go with 2 ways to integrate Azure with Dynamics CRM.

Hope that helps!

Show more