Custom Synchronization Provider for Sitecore Commerce Connect

I have been using Sitecore Commerce Connect for some time and customized it for project’s need. This is my first blog to share my knowledge about Commerce Connect and I am hoping many more to come in future.

Before I start talking about Commerce Connect, let make an announcement. I am thrilled to announce that, Sitecore awarded me as Technology MVP 2015.  I am one of 167 MVPs this year worldwide. I am so honored  to be part of such a talent group of people.

Back to Sitecore Commerce Connect. If you haven’t heard about Sitecore Commerce Connect or hadn’t have a chance to work on it, Commerce Connect is a Framework for connecting external eCommerce system with Sitecore. This integration of eCommerce System with Sitecore is very important because, a vast amount of online shopping websites out there uses Sitecore for Content Management and bringing eCommerce data in Sitecore empowers the marketers to increase the site’s visibility, specially, by using Sitecore Experience Platform (aka, DMS).

The Sitecore Commerce Connect is a separate module, available in SDN here. You will need Commerce Connect license to use this module. If you use partner license for the development, it is already included. Once you install Commerce Connect module and create a Product Repository folder from the Commerce Connect branch template, you should see following buttons on the Ribbon if you select the Product Repository folder item in the Content Editor.

Commerce Connect buttons

Clicking on the ‘Synchronize all products’ button will start synchronization of products and other related items. This doesn’t happen magically. We need to write many pipeline processors to get data from the external eCommerce and many configuration changes are needed. But, the basic flow is, clicking on ‘Synchronize all products’ calls a sitecore command, the command call the Commerce Connect’s Synchronization Provider and Synchronization Provider calls the pipelines where our code is to connect to the external eCommerce system and get the data.

This blog is to talk about, how we can replace the default Synchronization Provider with our custom Synchronization Provider. There can be many reason to do that. In my case I wanted to re-index the Product Repository immediately after importing the data. I said, re-index not rebuild index. To know more about how to programmatically re-index Sitecore items from a selected node, see this blog article that I wrote before.

The first thing we need to do is to change the ‘Synchronize all products’ command to call my command class. Below is the change that we need.

    <commands>
      <command name="synchronization:allproducts" type="My.Command.SynchronizeAllProducts, My.Command"
               patch:instead="command[@type='Sitecore.Commerce.Commands.Products.SynchronizeAllProducts, Sitecore.Commerce']"/>
    </commands>

My.Command.SynchronizeAllProducts needs to be derived from Sitecore.Commerce.Commands.Products.SynchronizeAllProducts.

The Execute method in My.Command.SynchronizeAllProducts class gets called. We will assign the custom Synchronization Provider here.

        public override void Execute(CommandContext context)
        {
            this.ProductSynchronizationProvider = new MyCustomProductSynchronizationProvider(context.Items[0]);
            base.Execute(context);
        }

Now, about the Custom Synchronization Provider. Here we are pausing the indexes, stopping events etc. and then calling the Product Synchronization pipeline. Once the products are synchronized, we are re-indexing the indexes selectively.

    public class MyCustomProductSynchronizationProvider : ProductSynchronizationProvider
    {
        private readonly Item _productRepositoryItem;

        public MyCustomProductSynchronizationProvider (Item productRepositoryItem)
        {
            _productRepositoryItem = productRepositoryItem;
        }

        public override ServiceProviderResult SynchronizeProducts(SynchronizationRequest request)
        {
            try
            {
                if (ContentSearchManager.SearchConfiguration != null)
                {
                    if (ContentSearchManager.SearchConfiguration.Indexes != null)
                    {
                        if (Enumerable.Any<KeyValuePair<string, ISearchIndex>>((IEnumerable<KeyValuePair<string, ISearchIndex>>)ContentSearchManager.SearchConfiguration.Indexes))
                        {
                            foreach (ISearchIndex searchIndex in ContentSearchManager.Indexes)
                            searchIndex.PauseIndexing();
                        }
                    }
                }
            }
            catch
            {
            }
            Settings.Indexing.Enabled = false;
            ServiceProviderResult serviceProviderResult;
            using (new SecurityDisabler())
            {
                using (new EventDisabler())
                {
                    using (new ProxyDisabler())
                    {
                        using (new DatabaseCacheDisabler())
                        {
                            using (new BulkUpdateContext())
                            {
                                request.Properties.Add("ContextItem", _productRepositoryItem);
                                serviceProviderResult = this.RunPipeline<SynchronizationRequest, ServiceProviderResult>("commerce.synchronizeProducts.synchronizeProducts", request);
                            }
                        }
                    }
                }
            }
            CacheManager.ClearAllCaches();
            Settings.Indexing.Enabled = true;
            try
            {
                if (ContentSearchManager.SearchConfiguration != null)
                {
                    if (ContentSearchManager.SearchConfiguration.Indexes != null)
                    {
                        if (Enumerable.Any<KeyValuePair<string, ISearchIndex>>((IEnumerable<KeyValuePair<string, ISearchIndex>>)ContentSearchManager.SearchConfiguration.Indexes))
                        {
                            foreach (ISearchIndex searchIndex in ContentSearchManager.Indexes)
                            {
                                searchIndex.ResumeIndexing();
                                if (searchIndex.Name.ToLower().Equals("sitecore_master_index"))
                                {
                                    searchIndex.Refresh(new SitecoreIndexableItem(this._productRepositoryItem));
                                }
                                else if (searchIndex.Name.ToLower().Equals("commerce_products_master_index"))
                                {
                                    searchIndex.Refresh(new SitecoreIndexableItem(this._productRepositoryItem));
                                }
                            }
                        }
                    }
                }
            }
            catch
            {
            }
            return serviceProviderResult;
        }

    }

That’s all, Commerce Connect calls the Custom Synchronization Provider where I can do the custom processing, before I call the Product Synchronization Pipeline.

Advertisements

About Himadri Chakrabarti

I am a software developer architect and a Sitecore MVP. My professional interest is everything and anything related to Software Architecture, .NET, Sitecore, Node.js, NoSQL etc. Outside of my profession, I am a hobbyist photographer. Link to my photography site http://himadriphotography.com/
This entry was posted in Commerce Connect and tagged , , , . Bookmark the permalink.

One Response to Custom Synchronization Provider for Sitecore Commerce Connect

  1. gorhal says:

    Hi Himadri
    Great post 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s