Where can I find sample code for Incoming Integration Bus functionality?

Lance Keay asked on May 3, 2016 11:20

Does anyone have some example code for using the Integration Bus... maybe a connector and REST service? The docs point to the SampleIntegratonConnector.cs which has a little bit of code for OUTGOING, but nothing for incoming, the methods are just stubbed.

I'm interested in syncing an external system's documents with a Kentico website, so I'll need to insert and update and delete documents.

I'm familiar with most other parts of the Kentico API, but I'm just not grokking how the Integration Bus connector should be implemented.

Recent Answers


Trevor Fayas answered on May 3, 2016 15:33

Here's from their documentation

General REST info
https://docs.kentico.com/display/K9/Kentico+REST+service

Code Example of REST
https://docs.kentico.com/display/K9/Sending+REST+requests+from+code

Integration BUS info
https://docs.kentico.com/display/K9/Using+the+integration+bus

Code example of BUS info
https://docs.kentico.com/display/K9/Example+-+Integration+connector

Do those help?

0 votesVote for this answer Mark as a Correct answer

Lance Keay answered on May 3, 2016 15:45

Thanks for the reply. I've already been through all the Kentico docs and I'm currently stuck as I can't find any examples on how to use the Integration Bus for incoming data.

Here's the main Kentico doc page: https://docs.kentico.com/display/K9/Implementing+incoming+synchronization that I've tried to follow.

0 votesVote for this answer Mark as a Correct answer

Lance Keay answered on May 3, 2016 17:55

Hi, I'm trying to sync objects from an external 3rd party into Kentico. I'm trying to use the Integration bus because the source has about 6000 documents in it, and takes too long to do realtime.

I've read the documentation on the Integration Bus https://docs.kentico.com/display/K9/Implementing+incoming+synchronization about incoming sync, but I have a problem where the update/insert is not appearing in the integration log.

FYI - the source is xml POSTed to a web api service. I'm looping through the xml and trying to add a document action to the queue for each document found in the xml.

In the REST service I am calling:

IntegrationHelper.ProcessExternalTask("ReportIntegrationConnector", e, IntegrationProcessTypeEnum.SkipOnError, CMS.DataEngine.TaskTypeEnum.CreateDocument, TaskDataTypeEnum.Simple, SiteContext.CurrentSite.SiteName);

Note: e is an XElelment containing the document data from the external system.

Upon calling the above, I can see that breakpoint and see an immediate hit to:

public override ICMSObject PrepareInternalObject(object obj, TaskTypeEnum taskType, TaskDataTypeEnum dataType, string siteName)
{
        XElement e = (XElement)obj;

        var node = CMS.DocumentEngine.TreeNode.New("custom.ReportCategory");
        node.DocumentName = "test";
        node.NodeParentID = 3;
        return node;
}

..And this looks good, however the task never appears in the Integration Bus > Incoming Tasks Queue

Would you have some sample code that I can use?

0 votesVote for this answer Mark as a Correct answer

Trevor Fayas answered on May 3, 2016 21:28 (last edited on May 3, 2016 21:30)

Two thoughts.

One is if the breakpoints hits immediately, it may remove itself from the incoming tasks queue before it hits it (which would make sense since the queue is waiting to run, so if it ran it would remove itself). So it may be operating exactly as it should.

If however i'm off and you're saying it's Preparing, but not making it to the integration bus from your 3rd party application, then after you prepare the node you may need to call another API piece for the integration bus to set it...There are some environment settings for integration bus as well that Kentico needs to have enabled, have you checked those?

Best guesses, i'm afraid i haven't done a lot with the integration bus as of yet.

0 votesVote for this answer Mark as a Correct answer

Lance Keay answered on May 4, 2016 09:37

Thanks Trevor, Timothy Fenton from Kentico support said a similar thing:

This setup actually looks perfectly fine, chances are it is getting processed before you even refresh the integration bus queue. You should make sure you have disabled the processing of these incoming tasks in Settings > Integration > Integration bus. Once this is disabled try hitting the webapi enpoint again with the object and see what happens. Chances are it will be logged just fine, especially since you are not even using the object that you are passing it, just giving it some test value. I configured a setup just like this for testing purposes and it works as expected.

So I unticked the 'process incoming' for the Integration Bus and it still didn't work. However, upon poking around some more, I saw a yellow warning triangle on my connector in the the CMS Integration Bus > Connectors. I'd had mispelt the codename!

Stupid error, but it's strange that the first part of the connector was properly breaking... so Kentico must have been finding the code. Because the breakpoint was being hit, I was working under the assumption that the connector was properly registered. ARgh.

So in case someone needs help with the code:

The web api service receives xml. I loop through the xml and extract the documents I need to process. For EACH document I stick the data from the xml into a simple struct to hold the incoming info:

public struct LightReportOrCategory
{
    public int SourceId;
    public int SourceParentId;

    public int KenticoId;
    public int KenticoParentId;

    public string ClassName;

    public string Name;
    public string Description;
    public bool Popular;
    public DateTime LastModified;
    public DateTime CreatedDate;
    public string Url;
}

Then I call the enqueuing function (lrc is the struct info):

  IntegrationHelper.ProcessExternalTask("ReportIntegrationConnector", lrc, IntegrationProcessTypeEnum.SkipOnError, CMS.DataEngine.TaskTypeEnum.CreateDocument, TaskDataTypeEnum.Simple, SiteContext.CurrentSite.SiteName); 

This immediately calls the Connector, in which I extract the info from the struct and assign to the TreeNode:

  public override ICMSObject PrepareInternalObject(object obj, TaskTypeEnum taskType, TaskDataTypeEnum dataType, string siteName)
    {
        // This method is called withing IntegrationHelper.ProcessExternalTask and it provides you with space where you can easily transform
        // external object (possibly some kind of data container) to TreeNode (document) or GeneralizedInfo (object - eg. UserInfo)


        var lroc = (CMSAppAppCode.Api.LightReportOrCategory)obj;

        CMS.DocumentEngine.TreeNode node = null;

        if(taskType == TaskTypeEnum.CreateDocument)
            node = CMS.DocumentEngine.TreeNode.New(lroc.ClassName);
        else
        {
            var tree = new CMS.DocumentEngine.TreeProvider();
            node = tree.SelectSingleNode(lroc.KenticoId);
        }


        node.DocumentName = lroc.Name;
        node.DocumentCulture = "en-US";

        node.SetValue("sourceId", lroc.SourceId);
        node.SetValue("Name", lroc.Name);
        node.SetValue("Description", lroc.Description);
        node.DocumentPublishTo = DateTime.UtcNow.AddYears(-1);//automatically unpublish


        //Reports have some extra attributes to set:
        if (lroc.ClassName == "custom.LibReports")
        {
            node.SetValue("popular", lroc.Popular);
            node.SetValue("LastModified", lroc.LastModified);
            node.SetValue("CreatedDate", lroc.CreatedDate);
            node.SetValue("Url", lroc.Url);
        }

        if(lroc.KenticoParentId >0)
            node.NodeParentID = lroc.KenticoParentId;
        else
        {
            if(node.NodeParentID <1)//set to the 'uncategorized' category
            {
                var tree = new CMS.DocumentEngine.TreeProvider();
                var nspUncat = new CMS.DocumentEngine.NodeSelectionParameters() { Where = "nodeGuid='d2803fab-1c69-43a8-aac2-c2ce541c2ae8'" };//'uncategorized' node guid=d2803fab-1c69-43a8-aac2-c2ce541c2ae8
                var reportsUncategorizedNode = tree.SelectSingleNode(nspUncat);

                node.NodeParentID = reportsUncategorizedNode.NodeID;

            }
        }

The Task then gets immediately enqueued in the incoming queue for the Integration Bus.

0 votesVote for this answer Mark as a Correct answer

Tobias Beckendorff answered on September 25, 2017 17:21

Hello Lance,

we followed your approach, thank you for the code example.

When we try to create a new document at a specific location in the page tree by setting the NodeParentID in PrepareInternalObject, it keeps getting created under root instead. The details of the incoming task are looking as expected, however. Also moving a page with TaskTypeEnum.UpdateDocument and setting NodeParentID works, too.

Any Suggestions? Thanks in advance,

Tobi

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.