In preparation for moving to CRM 2013 early in 2014, we recently upgraded the Cobalt suite of software components and applications to UR 15. The cross browser compatibility beginning with UR 12 has been a long time coming and with the recent compatibility issues we’ve experienced with Internet Exporer 10+, it had become even more apparent that browser compatibility was going to continue to be a support issue. Apart from browser compatibility issues, Cobalt has primarily only supported on-premise CRM installations up until recently due to limitations in the CRM Online environment. The upgrade to UR 15, with the added support for running custom workflows in isolation, was an opportunity to begin registering our plugins in isolation in our production environment to give us the ability to fully support CRM Online installations. plugin-cobalt

Beginning with version 2.4.2 of Cobalt’s CRM based suite of products, full support for plugins run in isolation as well as cross browser compatibility has been included. This change was not made without encountering a few roadblocks along the way. Particularly, there were 3 integration points that required updates and new solutions to fully support the CRM Online model for ISVs to integrate their solutions into the cloud environment.

  1. Cross Domain Scripting
  2. Plugin Timeout and Full Trust Operations.
  3. Plugin Tracing and SQL Transactions

Cross Domain Scripting

Cobalt’s solutions have traditionally relied heavily on a hosted web service for performing many client interactions in CRM. The javascript embedded in CRM forms use this service to handle retrieving data and executing server side code to validate forms, launch wizard processes and perform on the fly data operations. Traditionally, this service was hosted in an application running under the CRM website. However, such an application cannot exist in the CRM Online environment and is actually no longer supported in onpremise installations as of CRM 2013. The problem then is how to allow the javascript to communicate with this service when it now must be hosted in a separate site altogether.
For CRM onpremise installations the solution could have been as simple as creating a new website in the same domain as CRM, using a subdomain, so browsers wouldn’t be concerned with cross domain scripting. However, such a site could not be hosted in the same domain as CRM Online so that solution doesn’t work if we want to fully support CRM hosted anywhere.
The solution was simple enough if not obvious at first. I had seen other posts online related to working around the custom workflow issue for plugins in isolation, prior to UR 12, by using an entity and a plugin triggered on create to execute server side code. Essentially, the workflow would create the entity and the plugin would perform the function that would otherwise be performed by a custom workflow. Expanding on this idea we introduced a messaging entity to our Core solution that is responsible for dispatching events to our custom ISV code through this same mechanism. Since the web service was simply a proxy between our C# code that handled client side events, we decided to remove that proxy and create a new proxy via the CRM entity that executed the event handler code in a plugin triggered on create of the new entity. During the pre operation step of the create message for our new entity the client event handler code is executed and the response, which was previously passed back from the web service, is written to a field on the entity. The javascript populates the necessary information on the entity to allow the client event handlers to execute their function, saves the entity using the REST endpoint in CRM, and then reads the response and performs the actions specified.

Plugin Timeout and Full Trust Operations

The nature of plugins running in isolation (sandbox) is such that they can only execute partial trust operations. Access to the file system, registry, sql and external services (except HTTP / HTTPS) is prohibited. For the most part Cobalt’s products adhere to these guidelines to ensure support for plugins running in isolation and in the hosted CRM Online environment. However, there are functions of Cobalt’s system that are critical to our clients that cannot operate fully within the boundaries of the partial trust environment. The specific example I’ll use here is the data export module which was created to give users control over exporting data on a schedule and allow for uploading those exports to an external FTP site. The libraries we use to FTP files in our code use classes that are not isolatable and therefore cause runtime errors when executed in the sandbox environment.
The solution was again to create a new proxy to execute this code in an environment that does support full trust operations. In the previous section I discussed the Cobalt ISV application that was used for hosting the web service previously used by the javascript to execute server side code in CRM from the client. This application also hosts custom pages and controls that Cobalt’s products use to provide an interface to the end user. It was also a natural candidate for executing full trust operations as it is hosted outside of the CRM application. Where the ISV application was no longer usable for Client Events it became essential for executing server side event handlers that required a full-trust environment. The same messaging entity that is used by the javascript to execute server side code is used by the plugins to communicate with a web service running in the ISV application to execute full trust operations. The plugin decides based on it’s executing environment whether it should perform operations which require elevated trust within the plugin or pass the message on to the ISV web service for processing. Obviously there is a performance hit involved, however, in all cases there was a tradeoff to be made.

Plugin Tracing and SQL Transactions

Apart from performing full trust operations some operations of Cobalt’s products require CRUD operations to execute outside the database transaction that plugins execute under. When running plugins that are not isolated the code has access to the file system to perform tracing operations that assist with debugging. It also has the ability to create a new proxy using the CRM SDK to save / update records in CRM in a transaction separate from the main transaction that the proxy passed into the plugin executes under. When moving our plugins to isolation it quickly became apparent that neither of these functions was any longer supported. Queue the ISV application! Again the same proxy we used above for executing full trust operations such as FTP was the most obvious candidate for executing CRUD operations outside of the plugin transaction.
Cobalt’s auto numbering module, which creates unique identifiers for custom entities in the system, relies on this functionality to ensure uniqueness of values regardless of a failure in the primary transaction. Once the auto number is incremented it should never be rolled back even if an error occurs. So, in order for this to work, the increment has to happen outside of the plugin transaction. The ISV application creates a proxy to the CRM web service to perform the CRUD operation and returns to the plugin. In this way a new transaction is created for the auto number update and any subsequent failure cannot rollback that update.
Since the file system is no longer available for logging trace information the natural alternative is to log that information as records in CRM. However, in cases where we are trying to track down a failure in a plugin operation we don’t want the transaction with all of our tracing information to rollback before we have a chance to look at it. In the same manner as the auto number we need these trace records to be created outside of the plugin transaction and to do so we employ the ISV application web service to handle creating these log entries in CRM.

So what is the takeaway from our adventures into isolatable plugins, cross browser compatibility and full CRM Online support for Cobalt’s products? Well, in my opinion what we’ve discovered from all of this is Cobalt’s architecture is adaptable to almost any environment regardless of the restrictions set out by that environment. The total amount of time spent in development to provide support for UR 15 and Plugins in Isolation was about a week and a half. In the process we’ve more than prepared ourselves for CRM 2013 support in the coming months and CRM Online support while providing our customers with new more secure functionality and more hosting options than ever before.

Not bad for a week and a couple days worth of work.

Request a Demo