For the first time in weeks I’ve been able to work on the replication concept. As this excersize is intended to be a proof of concept, I decided to start with a small setup.
In order to replicate the data you need to have an entity in which the actual data is stored. In my scenario I called this entity “DataEntity”.
In the data entity I defined a couple of fields in which data is stored, as a bonus I added an additional technical column called “jcrm_sourceentityid”. This technical column is going to be used later on.
The other entity I defined is a message entity, called “MessageEntity”.
This is a special entity in which all changes in the data entity are going to be stored (field: “jcrm_sourceentitydata”), and is not intended for end users.
The columns I defined are the following:
The name of the action (“Create”, “Update”, “Delete”, “SetState”)
The id of the source entity (the entity the data came from)
The logical name of the source entity
Furthermore I’m going to use the “CreatedOn” column to decide the order of the actions, as the message entity is designed to work in a FiFo manner.
Data coming in first, will be processed first. Once a message record is processed, the message record will be deleted.
The basic plugin is fairly straight forward.
For every plugin step, I use the same plugin handler. In the handler I check the inputparameters to see where I do need to read the data from. From the input data, I exctract the Logical name of the entity and the Id.
I might need to extend this mechanism with a check on MessageName, otherwise I might delete the wrong records.
In case the target is an entity, I perform a retrieve action on the entity to get its actual state. Once retrieved I send the entity to a serializer to get an textual representation of the entity.
When developing it turned out that I can’t use the standard serializers in the .Net framework, as this part of the framework is not considered to be trusted . Therefor I need to use a custom serializer.
Google turned out to be my new #BF when I stumbled on the great blog post Charles Emes wrote. In this post he describes a workaround on how to serialize an entity to an Xml blob. Exactly what I need!
Once I created the plugin and I registered it on the jcrm_dataentity. Then I registered for the Create, Update, Delete, SetState/SetStateForDynamicEntity asynchronous post-operation steps. The replication I build is designed to work as a background process without having to bother the user with longer save times.
Once registered, I have the following plugin steps in place:
Time for a test drive
I added a new data entity, and did some modifications. Finaly I deleted the data entity.
I attached the plugin to my Visual Studio debugger in order to check if the changes were serialized correctly. I noticed in the example below that I’m missing some crucial data in order to serialize the data back to data types CRM can understand. I need to fix that issue…
Finally I checked the message entity in CRM to check if the data was written correctly.
As you can see I have a message entity in the MessageEntities view, when I open it, I see the XML in which the data is serialized.
So far so good. I proved that I’m able to catch the changed made to an entity in a very generic way. In case the data entity’s structure is extended, I don’t have to alter the code running in the plugin.
For now I have to focus on the serialization and deserialization. I have to do that by hand as binary serialization and the use of binary formatters is prohibited in the CRM sandbox (Microsoft considers a number of functions in the Microsoft .Net libraries as unsafe / untrusted code).
In the manual serialization I have to add some metadata to the fields I store, in order to determine what type of field it used to be.
Once this is solved, I can work on the message pump and setup a birectional scenario in which I have a use for the technical field “jcrm_sourceentityid”.
Man, I do love this stuff!