Is this really the version you are looking for? Kentico Xperience 8 Documentation is no longer updated. Use the switcher in the header to choose your product version.
To synchronize data from Kentico to external applications, you need to decide:
Use this information to implement the outgoing synchronization in your connector class:
Prepare subscriptions for the Kentico objects that you want to synchronize:
Use predefined subscription methods - allows you to easily subscribe to objects or documents OR
Build subscription objects - allows you to select exactly which objects are synchronized
You can create your own subscription class if you need to define custom options for the subscription scope.
Implement the method that converts objects or documents to the objects used by the external application.
(Optional) Implement translation of foreign key bindings:
Subscriptions keep track of actions that occur in Kentico, such as creating, updating or deleting objects and documents. Use subscriptions to determine the scope of the changes that the connector synchronizes.
You need to implement subscriptions inside the Init() method of your connector class:
using CMS.SynchronizationEngine;
using CMS.Synchronization;
using CMS.DataEngine;
public class CMSIntegrationConnector : BaseIntegrationConnector
{
public override void Init()
{
// Initializes the connector name
ConnectorName = GetType().Name;
// Register your subscriptions here
}
}You can subscribe to documents or objects by calling the following methods:
See Reference - Integration bus data types for information about the method parameters.
Examples:
// Subscribes to all types of changes made to user objects
SubscribeToObjects(TaskProcessTypeEnum.AsyncSnapshot, UserInfo.OBJECT_TYPE);// Subscribes to all types of changes made to all documents on all sites
SubscribeToAllDocuments(TaskProcessTypeEnum.AsyncSimpleSnapshot, TaskTypeEnum.All);You can select exactly which objects are synchronized using subscription objects:
Subscription classes inherit from AbstractIntegrationSubscription, and you can use the following predefined options:
The subscription classes provide the following filtering options:
BaseIntegrationSubscription
ObjectIntegrationSubscription
DocumentIntegrationSubscription
Wildcard character %
You can use the percent character (%) as a wildcard representing any number of characters in the string parameter values.
For example, if you specify the DocumentCultureCode as "en-%", the subscription covers all English cultures: en-US, en-GB, etc.
If you do not want to limit the synchronization scope through one of the properties, set the given value to null in the subscription object's constructor. For the TaskType enumeration, set the All value.
Examples:
// Subscription that synchronizes the creation of object types starting with 'poll.poll' - polls and poll answers
ObjectIntegrationSubscription objSub = new ObjectIntegrationSubscription(ConnectorName, TaskProcessTypeEnum.AsyncSnapshot, TaskTypeEnum.CreateObject, "PersonalSite", "poll.poll%", null);
SubscribeTo(objSub);
// Subscription that synchronizes all changes made to documents on 'NewSite', located under the /Home/ path in the content tree
DocumentIntegrationSubscription docSub = new DocumentIntegrationSubscription(ConnectorName, TaskProcessTypeEnum.AsyncSimpleSnapshot, TaskTypeEnum.All, "NewSite", "/Home/%", null, null);
SubscribeTo(docSub);// Subscribes to all changes made to the SETTINGS of a specific custom table, where 'customtable.SampleTable' is the table's code name
ObjectIntegrationSubscription customTableSub = new ObjectIntegrationSubscription(ConnectorName, TaskProcessTypeEnum.AsyncSimpleSnapshot, TaskTypeEnum.All, null, null, "customtable.SampleTable");
SubscribeTo(customTableSub);
// Subscribes to all changes made to the DATA of the 'customtable.SampleTable' custom table
ObjectIntegrationSubscription customTableDataSub = new ObjectIntegrationSubscription(ConnectorName, TaskProcessTypeEnum.AsyncSimpleSnapshot, TaskTypeEnum.All, null, CustomTableItemProvider.GetObjectType("customtable.SampleTable"), null);
SubscribeTo(customTableDataSub);If you need to extend the filtering options of a connector's subscriptions, you can create your own subscription class:
Create a new class inheriting from one of the existing subscription classes.
Define any properties and constructors that you need for the custom logic of your subscription class.
Override the IsMatch() method:
public override bool IsMatch(ICMSObject obj, TaskTypeEnum taskType, ref TaskProcessTypeEnum taskProcessType)
{
/* If you are inheriting from ObjectIntegrationSubscription or DocumentIntegrationSubscription,
* we recommend calling the IsMatch method of the parent class first:
* bool result = base.IsMatch(obj, taskType, taskProcessType)
* You can then use additional custom logic to modify the result. */
/* Evaluate whether the subscription's properties match the properties of the 'obj' parameter (TreeNode document or BaseInfo object)
* and the value of 'taskType'.
* Return a boolean value that indicates when objects match the subscription requirements. */
}You can then use the custom subscription class to build subscription objects.
To synchronize the objects covered by your subscriptions to external applications, you need to override methods inside your connector class:
The ProcessInternalTaskAsync method ensures asynchronous processing of objects (users, roles, forums, etc.) or documents (content tree nodes):
public override IntegrationProcessResultEnum ProcessInternalTaskAsync(GeneralizedInfo infoObj, TranslationHelper translations, TaskTypeEnum taskType, TaskDataTypeEnum dataType, string siteName, out string errorMessage)public override IntegrationProcessResultEnum ProcessInternalTaskAsync(TreeNode node, TranslationHelper translations, TaskTypeEnum taskType, TaskDataTypeEnum dataType, string siteName, out string errorMessage)The ProcessInternalTaskSync method ensures synchronous processing of objects (users, roles, forums, etc.) or documents (content tree nodes):
public override IntegrationProcessResultEnum ProcessInternalTaskSync(GeneralizedInfo infoObj, TaskTypeEnum taskType, string siteName, out string errorMessage)public override IntegrationProcessResultEnum ProcessInternalTaskSync(TreeNode node, TaskTypeEnum taskType, string siteName, out string errorMessage)In all cases, the purpose of the method is to transform the GeneralizedInfo or TreeNode internal object into a corresponding object in the third party system, and perform the action specified by TaskTypeEnum. You also have to take the TaskDataTypeEnum into account. When you are done with the processing, set the error message and return an IntegrationProcessResultEnum value.
For example:
public override IntegrationProcessResultEnum ProcessInternalTaskAsync(TreeNode node, TranslationHelper translations, TaskTypeEnum taskType, TaskDataTypeEnum dataType, string siteName, out string errorMessage)
{
// Convert the TreeNode to an external document object
// Optional: Translate foreign key values
// Send the data to the target application
// Method result for successful processing
errorMessage = null;
return IntegrationProcessResultEnum.OK;
}The synchronous and asynchronous versions of the methods work in the same way. The only difference is that you cannot use the TranslateColumnsToExternal method to translate foreign key values inside the ProcessInternalTaskSync method. If you wish to translate foreign keys with synchronous processing, you need to manually write the translation code.
Once you have converted the object or document to an external equivalent, there are several ways to synchronize the data with the target system:
You can use any other approach, but you always need to be able to determine whether the processing succeeded on the external side. Both the ProcessInternalTaskAsync and ProcessInternalTaskSync methods must return the result status.
The values of identifier columns may not always be the same for equivalent objects in Kentico and external systems. For subscriptions using the SimpleSnapshot or Snapshot data type and asynchronous processing, you can ensure consistency by translating the columns that store foreign key bindings to related objects.
To perform the translation, call TranslateColumnsToExternal inside your connector's ProcessInternalTaskAsync method. The TranslateColumnsToExternal method is inherited from BaseIntegrationConnector and accepts the following parameters:
TranslateColumnsToExternal(GeneralizedInfo infoObj, TranslationHelper translations, bool processChildren)TranslateColumnsToExternal(TreeNode node, TranslationHelper translations, bool processChildren)The last parameter determines whether to translate foreign keys of child objects. For the SimpleSnapshot data type, always pass false. The processChildren parameter is useful when using the Snapshot data type, for example when you are processing an object that does not exist in the target system yet, and you do no have enough transformation to translate the foreign keys of child objects before you process the main object. We recommend using the following translation order:
To ensure correct translation functionality, you need to override one or both of the following methods inside your connector class:
Override the GetExternalObjectID method inside your connector class if you call TranslateColumnsToExternal for objects or documents that have references to other objects inheriting from BaseInfo.
public override int GetExternalObjectID(string objectType, string codeName, string siteName, string parentType, int parentId, int groupId)Parameters:
Use the parameters to find the corresponding object in the external system and return the given object's identifier (integer value).
Override the GetExternalDocumentID method inside your connector class if you call TranslateColumnsToExternal for objects or documents that have references to other documents (TreeNode).
public override int GetExternalDocumentID(Guid nodeGuid, string cultureCode, string siteName, bool returnDocumentId)Parameters:
To learn how Kentico stores documents in the database, refer to Document database structure.
nodeGuid - the document's GUID (opens in a new tab) identifier.
cultureCode - the culture code of the document's language (for example en-US).
siteName - the code name of the site where the document belongs.
returnDocumentId - indicates which identifier you need to provide as the method's return value. If true, return the DocumentID, otherwise return the NodeID. The NodeID is an identifier of a tree node including all language versions, while DocumentID is unique for each language version.
Identifier | Alternative identification | |
|---|---|---|
Shared document data | NodeID | nodeGuid & siteName |
Culture version of a document | DocumentID | nodeGuide & siteName & cultureCode |
Use the parameters to find the corresponding document in the external system and return the given document's identifier (integer value).
If you need to translate ID column values to match external objects, we recommend using asynchronous processing. In synchronous mode, the only way to translate columns is to write custom code inside the ProcessInternalTaskSync method.
The following sample code indicates how to translate the identifier of a document's parent:
using CMS.DocumentEngine;
using CMS.Membership;
public override IntegrationProcessResultEnum ProcessInternalTaskSync(TreeNode node, TaskTypeEnum taskType, string siteName, out string errorMessage)
{
...
// Gets the Kentico parent node of the synchronized document
TreeProvider tree = new TreeProvider(MembershipContext.AuthenticatedUser);
TreeNode parentNode = DocumentHelper.GetDocument(node.NodeParentID, tree);
// Gets the properties of the parent node
Guid parentGuid = parentNode.NodeGUID;
string parentSiteName = parentNode.NodeSiteName;
int newParentId = 0;
// External code that finds the matching external document according to the parentNode properties, and fills the newParentID
// Assigns the new parent ID to the synchronized document
node.NodeParentID = newParentId;
...
}