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.