Monday, March 7, 2011

Windows Azure AppFabric and Integration with CRM 2011 Online

This post describes how to send messages in real time from CRM 2011 Online back to a company premises using Windows Azure.  If you were using CRM 2011 On Premise you would use a plug-in and attach it to the create or update event of an entity.  The plug-in code might write out the mesage in XML format for integration with an internal system.  So how do you do this with CRM 2011 Online? The answer is to use the Windows Azure AppFabric because there is built in support for this in CRM 2011 Online. 

Basically what you need to do is create a Service Bus on Windows Azure and then create a namespace.  So you need to go through the steps of creating a Windows Azure account and set up a unique namespace.  That will generate a "Current Management Key" whic you will need when you register the endpoint in the Plugin-tool.  This post has a good description on how to do it. 

You need to log into CRM Online and dowlnload the certificate that you need for the Plugin. Goto Settings -> Customizations -> Developer Resources and select download certificate. Make a note of the Issuer name directly above the link (e.g. crm4.dynamics.com).


Back in your development environment you will need to ensure you have the Windows Azure SDK and CRM 2011 SDK installed. You can use the sample code provided in the CRM SDK located at C:\CRMSDK\sdk\samplecode\cs\azure\onewaylistener.   This is the application that will listen for messages that are sent to the Azure endpoint.  The class implements IServiceEndpointPlugin and the class name serves as your "Contract" (you will use it as the "Path"  when you configure the endpoint).

Open the CRM Plugin tool and configure a Service EndPoint.  This post describes how to configure the Service Endpoint. The Solution Namespace is the same as the namespace you created in Azure.  The Path is where you enter the class name of your listener application.  Click Save and Configure ACS. You will be prompted for the location of the certificate and the issuer name. You are also prompted for the Management Key and this is current Management Key from the Windows Azure namespace.  Click on "Save and verify authentication" which should verify the connection with a success message.  Click on "Close". 

Beneath the Service Endpoint you can now add a Step and configure it as you would have done for an On Premise plugin only now the event handler is the service endpoint you just created. You could for example set the plugin to fire on the Create event for the Contact entity. 

That done you can now configure the app.comfig with your (Azure) Service Namespace, Isssuer Secret (your Azure Management Key)  and the Service Path which is the name of your listener class.  Run your OneWayListener application, and that should open a connection to your Azure endpoint and will print out messages as they are received to the console window.

So now go to CRM 2011 Online and perform the action that your Plugin is attached to (e.g. create contact). After you save the Contact, the Asynchronous process runs and your listener will receive the message. 

The Onewaylistener code uses a RemoteExecutionContext object which has all the information you need from the User Guid to the Organization Guid. The interesting stuff  is in the context.InputParameters collection. It contains all the data you entered. Its a simple task to turn this into XML and then you are all set to integrate with whatever you want.

Saturday, March 5, 2011

Connecting to CRM 2011 in the Cloud

Connecting to CRM 2011 in the Cloud is trickier than connecting to CRM 2011 On Premise.
There is a great article by Deepak Kumar but it is worth recapping on his points.
Check c:\Program Files to see if you have Windows Identity Foundation. If not you will need to install it.

You need to get some device credentials and this is done using a utility in the CRMSDK called DEVICEREGISTRATION. Go to \sdk\tools\deviceregistration directory and load deviceregistration.csproj. Compile the application and navigate to the \bin\debug folder. Open a command window and type

deviceregistration.exe /operation:Register

The Device ID and Password that are generated are used in the method GetDeviceCredentials (that comes next).

Preparation work done you can now create your VS 2010 project, in this example I am using a WCF Service (I left the default name of Service)

Copy the CRMServiceHelper.cs file from \sdk\samplecode\cs\helpercode into your project and modify three methods:

GetDeviceCredentials
GetUserLogonCredentials
GetServerConfiguration

I used the code in Deepak Kumar's blog and set my Windows LiveID credentials in the GetUserLogonCredentials method. When you set the endpoints in GetServerConfiguration be aware that endpoints vary depending where you are in the world so see this blog .

Then if you want Intellisense on your custom entities and attributes you need to generate a class with them all in using CRMSVCUTIL.EXE. This tool is in the SDK too in the \sdk\bin directory. Amend your Environment Path so you have a reference to its location. Open a Command window, navigate to where you want the class to be generated then use

CrmSvcUtil.exe /url:https://{organisation}.crm4.dynamics.com/XRMServices/2011/Organization.svc /out:GeneratedCode.cs /username:"windows live id" /password:"live id password" /deviceid:"deviceid" /devicepassword:"device password"

Add the class you just generated to your project. OK, this takes a while and you will have to keep regenerating it every time you add an attribute but think of the time you'll save by having fewer bugs.

You will need to add references to the CRM SDK dlls (microsoft.crm.sdk.proxy.dll, microsoft.xrm.sdk.dll and microsoft.crm.sdk.dll) and then add these using statements

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Crm.Sdk.Messages;


Add 3 declarations in the class Service.
private OrganizationServiceContext context;
private OrganizationServiceProxy proxy;
private IOrganizationService service;


In the class constructor add a call to ConsumeIOrganization().

public Service()
{
ConsumeIOrganization();
}
Then add two methods

public void ConsumeIOrganization()
{
ServerConnection serverConnection = new ServerConnection();
ServerConnection.Configuration serverConfig = serverConnection.GetServerConfiguration();
Connect(serverConfig);
}

public void Connect(ServerConnection.Configuration serverConfig)
{
try
{
using (proxy = new OrganizationServiceProxy(serverConfig.OrganizationUri, serverConfig.HomeRealmUri,
serverConfig.Credentials, serverConfig.DeviceCredentials))
{
proxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
context = new OrganizationServiceContext(proxy);
service = (IOrganizationService)proxy;
}
}
catch (FaultException <microsoft.xrm.sdk.organizationservicefault>)
{
throw;
}
}

Now you can add your code and reference service or context methods depending on which you prefer. Welcome to programming in the cloud!